[react]KakaoMap APIをPolyline画像にアップロードする


それぞれ選択した線とタグ(移動中、アクセス先)に写真とテキストを保存するので、写真の部分をアップロードしてみました

0、成果物



1.実施内容


何枚も写真をアップします
アップロード後すぐにサーバに保存します.
保存したパスをフロントから受信して画面に表示
画像をクリックすると削除されます

2. react-dropzone


https://react-dropzone.js.org/
リンクに入るとreact-dropzoneの詳細が表示されます
主にHookを使った例がたくさんありますが、私は素子で描きました.

59号線のようにアイコンを追加し、53号はスタイルにサイズを調整するなど
ファイルのアップロード時に、最も重要なprops onDropに対して以下の処理が行われた.もしあなたが多くのことをしなければならないなら、multipleの属性をくれます.

複数のイベントを処理するため、各ファイルにはformDataで受信したファイルが含まれます.
このとき,19行目には"file"があり,このファイルをサーバに渡す際には,区切り記号のような概念と考えられる.実は画像をアップロードするなら"image"が一番いいです.サーバがアップロード部分を処理する場合、低オプションを使用してブランチ処理を行うことができます.
21番線上ではそのように属性を与え、26番線上でapiで公開するとデータはサーバに転送されます.
28号線がサーバに保存に成功した後に応答を受けた場合、ファイルはストレージパスに転送されます.それをsetImage(newImgList)にして、画像を保存する経路を作って、スクリーンにこぼしたり、保存したりするときに使います.

3.保存画像Back-end


multerという名前のライブラリを使用しました
193号線郵送後、197号はuploadを搭載
191行では、upload変数のうちstorageがファイルの格納位置と格納時のファイル名を決定し、.array('file',10)が受信したデータが配列である場合、区切り記号をファイルとして受信し、最大値は10と指定する!
詳しくは、ドキュメントとグーグルがすぐに出てきました.
.arrayで受信すると、後ろの最大ファイル数はいくらですか?記入しなければ動作しません

4.残りのこと

  • polyline.jsで「保存」ボタンをクリックすると、画像、テキストおよび記述データがPOST方式でサーバ
  • に保存する.

    5.ソース


    polyline.js
    import React, { useEffect, useState } from 'react'
    import { Button, Form, Input } from 'antd'
    import ImageUpload from '../../../utils/ImageUpload'
    import _ from 'lodash';
    
    function Polyline(props) {
        const { TextArea } = Input
        const [CurData, setCurData] = useState([])
        const [HeaderText, setHeaderText] = useState("")
        
        useEffect(() => {
            setCurData(props.polyline)
        }, [props.polyline])
    
        useEffect(() => {
            if(CurData) {
                const tempIdx = _.get(CurData[0], 'index') ? _.get(CurData[0], 'index') : "항목을 선택하세요"
                setHeaderText(`# ${tempIdx}`)
            }
        }, [CurData])
    
    
        const submitHandler = (event) => {
            event.preventDefault() //확인눌렀을때 화면을 다시 그리지 않게 해줌
        }
        
        
        return (
            <div>
                {CurData && 
                    <Form onSubmit={submitHandler}>
                        <div>
                            <ImageUpload
                                imgFlag={HeaderText}/>                                        
                        </div>
    
                        <div>
                            <div style={{margin: "10px", fontSize: "16px"}}>
                                {HeaderText}
                            </div>
                            <div style={{margin: "10px"}}>
                                <label>Title</label>
                                <Input value={CurData.endTime} />
                            </div>
    
                            <div style={{margin: "10px"}}>
                                <label>Description</label>
                                <TextArea value={CurData.endTime} rows={4}/>
                            </div>
    
                            
                            <div style={{margin: "10px"}}>
                                <Button htmlType="submit">
                                    저장
                                </Button>
                            </div>
                        </div>
                </Form>
                }
            </div>
        )
    }
    
    export default Polyline
    ImageUpload.js
    import React, { useEffect, useState } from 'react'
    import Dropzone from 'react-dropzone'
    import { Icon } from 'antd'
    import axios from 'axios'
    
    function FileUpload(props) {
    
        const [Images, setImages] = useState([])
        const [DisabledFlag, setDisabledFlag] = useState(true)
    
        useEffect(() => {
            setImages([])
            props.imgFlag === '# 항목을 선택하세요' ? setDisabledFlag(true) : setDisabledFlag(false)
        }, [props.imgFlag])
    
        const dropHandler = (files) => {
            let formData = new FormData()
            for(let i = 0; i < files.length; i++){
                formData.append("file", files[i])
            }
            const config = {
                headers: {
                    'Content-Type': 'multipart/form-data'
                }
            };
            axios.post('/api/polyline/image', formData, config)
            .then(response => {
                if(response.data.success){
                    let newImgList = [...Images]
                    response.data.files.map((cur) => {
                        newImgList.push(cur.path)
                    })
                    setImages(newImgList)
                } else{
                    alert('파일 저장 실패!')
                }
            })
        }
        
    
        const deleteHandler = (image) => {
            setImages(Images.filter((key) => key !== image))
        }
    
        return (
            <div style={{display:'flex', justifyContent:'space-between'}}>
                <Dropzone
                    //disabled={DisabledFlag} 
                    onDrop={dropHandler}
                    multiple>
                    {({getRootProps, getInputProps}) => (
                    <section>
                    <div style={{
                        width:300, height: 240, border:'1px solid lightgray',
                        display:'flex', alignItems: 'center', justifyContent:'center'
                        }}
                        {...getRootProps()}>
                        <input {...getInputProps()} />
                        <Icon type="plus" style={{ fontSize:'3rem'}}/>
                    </div>
                    </section>
                )}
                </Dropzone>
    
                <div style={{ width:'350px', height: '240px', overflowY:'scroll'}}>
                    {Images.map((image, index) => (
                        <div key={index} onClick={() => deleteHandler(image)}>
                            <img style={{minWidth:'300px', width:'300px', height:'240px'}}
                            src={`http://localhost:5000/${image}`}/>
                        </div>
                    ))}
                </div>
            </div>
        )
    }
    
    export default FileUpload