programing

리액트 리셋 방법JS 파일 입력

newstyles 2023. 3. 10. 21:20

리액트 리셋 방법JS 파일 입력

파일 업로드 입력이 있습니다.

<input onChange={this.getFile} id="fileUpload" type="file" className="upload"/>

업로드 처리 방법은 다음과 같습니다.

getFile(e) {
    e.preventDefault();
    let reader = new FileReader();
    let file = e.target.files[0];
    reader.onloadend = (theFile) => {
        var data = {
            blob: theFile.target.result, name: file.name,
            visitorId:  this.props.socketio.visitorId
        };
        console.log(this.props.socketio);
        this.props.socketio.emit('file-upload', data);
    };
    reader.readAsDataURL(file);
}

동일한 파일을 두 번 업로드하면 업로드 이벤트가 발생하지 않습니다.어떻게 하면 고칠 수 있을까요?단순 js 코드의 경우 변경 핸들러에서 this.value = null;을 수행하기에 충분했습니다.React JS에서는 어떻게 하면 좋을까요?

다음과 같이 입력값을 클리어할 수 있습니다.

e.target.value = null;

파일 입력을 제어할 수 없습니다. 특별한 리액트 방법은 없습니다.


편집 오래된 브라우저(<IE11)의 경우 다음 기술 중 하나를 사용할 수 있습니다.

http://jsbin.com/zurudemuma/1/edit?js,output 를 참조해 주세요(IE10 및 9 에 기재되어 있습니다).

나한테 효과가 있었던 건...key파일 입력에 속성을 부여하고 리셋이 필요할 때 키 속성 값을 업데이트합니다.

functionThatResetsTheFileInput() {
  let randomString = Math.random().toString(36);

  this.setState({
    theInputKey: randomString
  });
}

render() {
  return(
    <div>
      <input type="file"
             key={this.state.theInputKey || '' } />
      <button onClick={this.functionThatResetsTheFileInput()} />
    </div>
  )
}

그러면 React가 입력을 처음부터 다시 렌더링합니다.

저는 이 방법으로 - ref={ref = >이렇게 하면 됩니다.fileInput = ref}

<input id="file_input_file" type="file" onChange={(e) => this._handleFileChange(e)} ref={ref=> this.fileInput = ref} />

그리고 내 경우, 파일이 서버에 업로드되면 아래 명령어를 사용하여 파일을 지웁니다.

 this.fileInput.value = "";

업데이트를 통해 수행합니다.key내 파일 입력 안에 있습니다.이렇게 하면 강제로 재렌더가 실행되어 이전에 선택한 파일이 사라집니다.

<input type="file" key={this.state.inputKey} />

상태 변경inputKey컴포넌트를 재설치합니다.1가지 방법으로inputKey항상 로 설정합니다.Date.now()버튼을 클릭하면 필드가 클리어 됩니다.

클릭할 때마다onClick같은 파일이라도 입력을 리셋할 수 있습니다.onChange트리거 됩니다.

<input onChange={this.onChange} onClick={e => (e.target.value = null)} type="file" />
import React, { useRef } from "react";

export default function App() {
  const ref = useRef();

  const reset = () => {
    ref.current.value = "";
  };

  return (
    <>
      <input type="file" ref={ref} />
      <button onClick={reset}>reset</button>
    </>
  );
}

리액트 훅을 사용하여 다음과 같은 작업을 수행했습니다.이는 "제어된 입력"이라고 알려진 것을 사용하여 수행됩니다.즉, 입력은 주()에 의해 제어되거나 그 진실의 출처가 주(州)에 의해 제어됩니다.

TL;DR 파일 입력 리셋은 2단계 프로세스로,useState()그리고.useRef()훅을 클릭합니다.

메모: 다른 사람이 궁금해할 경우를 대비해 텍스트 입력을 리셋하는 방법도 기재했습니다.

function CreatePost({ user }) {
    const [content, setContent] = React.useState("");
    const [image, setImage] = React.useState(null); //See Supporting Documentation #1
    const imageInputRef = React.useRef(); //See Supporting Documentation #2

    function handleSubmit(event) {
        event.preventDefault(); //Stop the pesky default reload function
        setContent(""); //Resets the value of the first input - See #1

        //////START of File Input Reset
        imageInputRef.current.value = "";//Resets the file name of the file input - See #2
        setImage(null); //Resets the value of the file input - See #1
        //////END of File Input Reset
    }

    return (
    <div>
        <form onSubmit={handleSubmit}>
            <input 
            type="text" 
            placeholder="Add Post Content" 
            onChange={event => setContent(event.target.value)}
            value={content} //Make this input's value, controlled by state
            />
            <input 
            type="file"
            onChange={event => setImage(event.target.files[0])} //See Supporting Doc #3
            ref={imageInputRef} //Apply the ref to the input, now it's controlled - See #2
            />
            <button type="submit">Submit Form</button>
        </form>
    </div>
    )
};

지원 자료:

  1. useState Hook(후크 상태)
    • 스테이트풀값과 이를 갱신하는 함수를 반환합니다.
  2. useRef 훅
    • ref 객체를 React에 전달하면 React는 노드가 변경될 때마다 해당 DOM 노드에 현재 속성을 설정합니다.
  3. 웹 앱의 파일 사용
    • 사용자가 파일을 하나만 선택할 경우 목록의 첫 번째 파일만 고려하면 됩니다.

내장된 파일 입력 값을 전혀 사용하지 않을 경우 이 값을 입력 요소에 포함할 수도 있습니다.

<input value={""} ... />

이렇게 하면 값이 항상 렌더링의 빈 문자열로 재설정되므로 onChange 함수에 어색하게 포함할 필요가 없습니다.

파일 입력이 항상 제어되지 않는다는 것을 알지만, 다음 코드는 여전히 내 자신의 porject에서 작동하기 때문에 나는 전혀 문제없이 입력을 리셋할 수 있다.

constructor(props) {
    super(props);
    this.state = {
        selectedFile: undefined,
        selectedFileName: undefined,
        imageSrc: undefined,
        value: ''
    };

    this.handleChange = this.handleChange.bind(this);
    this.removeImage = this.removeImage.bind(this);
}

handleChange(event) {
    if (event.target.files[0]) {
        this.setState({
            selectedFile: event.target.files[0],
            selectedFileName: event.target.files[0].name,
            imageSrc: window.URL.createObjectURL(event.target.files[0]),
            value: event.target.value,
        });
    }
}

// Call this function to reset input
removeImage() {
    this.setState({
        selectedFile: undefined,
        selectedFileName: undefined,
        imageSrc: undefined,
        value: ''
    })
}

render() {
    return (
        <input type="file" value={this.state.value} onChange={this.handleChange} />
    );
}

, 를 합니다.key = {this.state.fileInputKey} initial sing " " " 입니다.fileInputKey로로 합니다.Date.now()이치노하면 fileInputKey에 의해, 값이 , 의 「FileInputKey: Date.now()」에 파일 됩니다.이것에 의해, 이전과 다른 값이 되어, 다음에 새로운 파일 입력 컴포넌트가 작성됩니다.render()

이 조작은 수동으로 실행할 수도 있습니다.버튼을 클릭하여 파일을 클리어/리셋합니다.입력

작업 코드는 다음과 같습니다.

import React from "react";
import { Button } from "reactstrap";

class FileUpload extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedFile: null,
      fileInputKey: Date.now(),
      message: ""
    };
    this.handleClear = this.handleClear.bind(this);
    this.onClickHandler = this.onClickHandler.bind(this);
    this.onChangeHandler = this.onChangeHandler.bind(this);
  }

  onChangeHandler = event => {
    this.setState({
      selectedFile: event.target.files
    });
  };

  onClickHandler = () => {
    if (this.state.selectedFile === null) {
      this.setState({
        message: "Please select File"
      });
      return;
    }
    //axios POST req code to send file to server
    {
      /**        
         const data = new FormData()
    data = this.state.selectedFile[0]                
      axios.post("http://localhost:8080/api/uploadFile/", data)
               .then(res => { 
             if (res.status == 200) {
           // upload success
             }                
               })
               .catch(err => { 
                  //message upload failed
               })    
    */
    }
//after upload to server processed

    this.setState({
      selectedFile: null,
      fileInputKey: Date.now(),
      message: "File Uploaded"
    });
  };

  handleClear() {
    this.setState({
      selectedFile: null,
      fileInputKey: Date.now(),
      message: ""
    });
  }

  render() {
    return (
      <div>
        <input
          type="file"
          key={this.state.fileInputKey}
          class="form-control"
          onChange={this.onChangeHandler}
        />
        <button
          type="button"
          class="btn btn-success btn-block"
          onClick={this.onClickHandler}
        >
          Upload
        </button>
        <Button
          type="button"
          value="Clear"
          data-test="clear"
          onClick={this.handleClear}
        >
          {" "}
          Clear{" "}
        </Button>

        <br />
        <label>{this.state.message}</label>
      </div>
    );
  }
}

export default FileUpload;

redux 폼을 사용한 솔루션

class FileInput extends React.Component {
  constructor() {
    super();

    this.deleteImage = this.deleteImage.bind(this);
  }

  deleteImage() {
    // Just setting input ref value to null did not work well with redux form
    // At the same time just calling on change with nothing didn't do the trick
    // just using onChange does the change in redux form but if you try selecting
    // the same image again it doesn't show in the preview cause the onChange of the
    // input is not called since for the input the value is not changing
    // but for redux form would be.

    this.fileInput.value = null;
    this.props.input.onChange();
  }

  render() {
    const { input: { onChange, value }, accept, disabled, error } = this.props;
    const { edited } = this.state;

    return (
      <div className="file-input-expanded">
        {/* ref and on change are key properties here */}
        <input
          className="hidden"
          type="file"
          onChange={e => onChange(e.target.files[0])}
          multiple={false}
          accept={accept}
          capture
          ref={(input) => { this.fileInput = input; }}
          disabled={disabled}
        />
        {!value ?
          {/* Add button */}
          <Button
            className="btn-link action"
            type="button"
            text="Add Image"
            onPress={() => this.fileInput.click()}
            disabled={disabled}
          />
          :
          <div className="file-input-container">
            <div className="flex-row">
              {/* Image preview */}
              <img src={window.URL.createObjectURL(value)} alt="outbound MMS" />
              <div className="flex-col mg-l-20">
                {/* This button does de replacing */}
                <Button
                  type="button"
                  className="btn-link mg-b-10"
                  text="Change Image"
                  onPress={() => this.fileInput.click()}
                  disabled={disabled}
                />
                {/* This button is the one that does de deleting */}
                <Button
                  type="button"
                  className="btn-link delete"
                  text="Delete Image"
                  onPress={this.deleteImage}
                  disabled={disabled}
                />
              </div>
            </div>
            {error &&
              <div className="error-message"> {error}</div>
            }
          </div>
        }
      </div>
    );
  }
}

FileInput.propTypes = {
  input: object.isRequired,
  accept: string,
  disabled: bool,
  error: string
};

FileInput.defaultProps = {
  accept: '*',
};

export default FileInput;

제 경우 기능하는 컴포넌트를 가지고 있었는데, 파일을 선택한 후 파일명을 설정하게 되어 있기 때문에 위와 같이 수정한 ref를 제외하고 위의 어떤 솔루션을 사용해도 오류가 발생하였습니다.

const fileUpload = props => {

    const inputEl = useRef(null)
    const onUpload = useCallback(e => {
         uploadFile(fileDetails)
            .then(res => {
                 inputEl.current.value = ''  
            })
            .catch(err => {
                 inputEl.current.value = ''
            })
    })
    
    return (
        <input type='file' ref={inputEl} onChange={handleChange} />
        <Button onClick={onUpload}>Upload</Button>
    )
}

최근에 File type 입력 필드를 리셋하기 위해 이 문제에 부딪혔습니다.대부분의 개발자들에게는 여전히 이정표라고 생각합니다.그래서 저는 저의 해결책을 공유해야겠다고 생각했습니다.

이미지 파일을 몇 가지 상태로 업데이트하기 위해 onChange 이벤트를 듣고 있기 때문에 상태를 설정하면 컴포넌트가 다시 렌더링됩니다.이 경우 입력 파일의 값을 빈 like value="로 지정하면 값이 변경될 때마다 입력 필드가 값을 리셋합니다.

 <input  
  type="file"
  value=''
  onChange={onChangeFnc}
 /> 

언급URL : https://stackoverflow.com/questions/42192346/how-to-reset-reactjs-file-input