ReactJS: проблема с поддельным путем в повторителе

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я создал повторитель, поэтому, когда пользователь нажимает на значок плюса, добавляется новая строка с двумя тегами ввода. Ниже приведен мой код: repeater.js

 import React from "react"
const Details = (props) => {

  return (
    props.Desc !== '' ?
      props.Desc.map((val, idx) => {
        let desc = ` desc-${idx}`, file = `file-${idx}`
        return (
          <tr key={val.index}>
            <td> Description</td>
              <td >
                <input type="text" defaultValue={val.desc} name="desc" data-id={idx} id={desc} className="form-control " />
              </td>

            <td className="mr-2">  Files</td>
            <td>
              <input type="file" defaultValue={file} name="file" id={file} data-id={idx} className="form-control " />
            </td>
            <td>
              {
                idx === 0 ? <button onClick={() => props.add()} type="button" className="btn btn-primary text-center"><i className="fa fa-plus-circle" aria-hidden="true"></i></button>
                  : <button className="btn btn-danger" onClick={(() => props.delete(val))} ><i className="fa fa-minus" aria-hidden="true"></i></button>
              }
            </td>
          </tr >
        )
      })
      : null
  )
}
export default Details

 

Details.js

 import React, { Fragment, Component } from 'react'
import Details from './repeater.js'

class CreateDetail extends Component {
    constructor(props) {
        super(props);

        this.state = {
            inputList: [{ index: Math.random(), desc: "", file: "" }],
        }
    }

    onSubmit = (e) => {
        console.log('data : ', this.state.inputList[0]);
    }

     handleChange = (e) => {
         if (["desc", "file"].includes(e.target.name)) {
             let Desc = [...this.state.inputList]
             inputList[e.target.dataset.id][e.target.name] = e.target.value;
         } else {
             this.setState({ [e.target.name]: e.target.value })
         }
     }

    addNewRow = (e) => {
    this.setState((prevState) => ({
    inputList: [...prevState.inputList, { index: Math.random(), desc: "", file: "" }],
       }));
    }

     deteteRow = (index) => {
        this.setState({
             inputList: this.state.inputList.filter((s, sindex) => index !== sindex),
         });
     }

    clickOnDelete(record) {
       this.setState({
          inputList: this.state.inputList.filter(r => r !== record)
      });
    }

    render() {
        let { inputList, flag } = this.state
        return (
            <Fragment>
                <div className="container-fluid">
                    <div className="row">
                        <div className="col-sm-12">
                            <div className="card">
                                <div className="card-body">
                                    <form className="needs-validation" onChange={this.handleChange}>
           <div className="form-group row">
             <label className="col-xl-3 col-md-3">Details</label>
                 <div className="col-9 col-md-9">
                    <table className="table">
                        <tbody>
                          <Details add={this.addNewRow} delete={this.clickOnDelete.bind(this)} Desc ={inputList} />
                        </tbody>
                    </table>
                </div>
            </div>
                <div className="pull-right">
                       <button type="button" className="btn btn-primary" onClick={this.onSubmit}> save </button>
                                        </div>
                                    </form>
                                </div>
                            </div>
                        </div>
                    </div >
                </div >
            </Fragment >
        )
    }
}

export default CreateDetail

 

Но я сталкиваюсь с одной проблемой: когда я использую тип входного тега «file» и загружаю изображение, я получаю поддельный путь, как показано ниже.

 C:fakepath6t8Zh249QiFmVnkQdCCtHK.jpg
 

Я сталкиваюсь с этой проблемой только в repeater. Если я использую входной тег с типом «file» вне repeater, то я получаю правильный путь.

Поддельный путь является основной проблемой, потому что, если я извлекаю имя файла и загружаю его в s3, тогда пустое изображение загружается в s3. Как я могу загрузить файл в repeater?

Ответ №1:

браузер не позволит получить локальный путь к файлу.вы можете использовать данные как данные формы и сохранять их в состоянии и отправлять их в S3. like

       handleChange = (e) => {
             let formData = new FormData
for (var i = 0; i < e.target.files.length; i  ) {
    formData.append(e.target.name, e.target.files[i])
}
             .....

         }
 

Комментарии:

1. Спасибо. Я использовал данные формы, и это частично решило проблему. Я имею в виду, что теперь я получаю объект file вместо поддельного пути. Но в repeater, когда я добавляю новую строку и загружаю другое изображение, я получаю только файловый объект первого изображения. Но отправка должна возвращать все загруженные изображения, что равно 2

2. теперь проверьте код. вы можете изменить имя добавляемого файла, изменив e.target.name . также e.target. файлы будут содержать выбранный вами массив файлов