我正在尝试根据承诺更新状态。但是组件将无休无止地反复执行,直到达到最大堆大小为止。我不知道我在这里想念什么。
这是我的代码

import {useDropzone} from 'react-dropzone';
import File from './File'
import parser from 'subtitles-parser'

const baseStyle = {
  flex: 1,
  display: 'flex',
  flexDirection: 'column',
  alignItems: 'center',
  padding: '20px',
  borderWidth: 2,
  borderRadius: 2,
  borderColor: '#eeeeee',
  borderStyle: 'dashed',
  backgroundColor: '#fafafa',
  color: '#bdbdbd',
  outline: 'none',
  transition: 'border .24s ease-in-out'
};

const activeStyle = {
  borderColor: '#2196f3'
};

const acceptStyle = {
  borderColor: '#00e676'
};

const rejectStyle = {
  borderColor: '#ff1744'
};

function Drag(props) {
  const {
    getRootProps,
    getInputProps,
    isDragActive,
    isDragAccept,
    isDragReject,
    acceptedFiles
  } = useDropzone();

  const style = useMemo(() => ({
    ...baseStyle,
    ...(isDragActive ? activeStyle : {}),
    ...(isDragAccept ? acceptStyle : {}),
    ...(isDragReject ? rejectStyle : {})
  }), [
    isDragActive,
    isDragReject
  ]);
  const [data, setData] = useState(null)
  if(acceptedFiles.length === 1){
    const  readUploadedFileAsText = (acceptedFiles) => {
      const temporaryFileReader = new FileReader();
      return new Promise((resolve, reject) => {
        temporaryFileReader.onerror = () => {
          temporaryFileReader.abort();
          reject(new DOMException("Problem parsing input file."));
        };

        temporaryFileReader.onload = () => {
          resolve(parser.fromSrt(temporaryFileReader.result));
        };
        temporaryFileReader.readAsText(acceptedFiles);
      });
    };
    let file = acceptedFiles[0]
    readUploadedFileAsText(file)
    .then(res => {
      setData({
        data: res
      })
    })
  }

  return (
    <div className="container">
      <div {...getRootProps({style})}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
      <File file={data} />
      {console.log(data)}
    </div>
  );
}

export default Drag


让我知道是否必须使用任何生命周期方法。我尝试使用componentDidMount和componentWillReceiveProps,但两者都对我不起作用,或者我没有以正确的方式完成操作。

最佳答案

将readUploadedFileAsText函数放在if语句之外。然后可以将if和函数调用添加到React.useEffect,它将在初始加载时调用该函数,但不会在以后的每次重新渲染时调用。

function Drag(props) {
    const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject, acceptedFiles } = useDropzone();

    const style = useMemo(
        () => ({
            ...baseStyle,
            ...(isDragActive ? activeStyle : {}),
            ...(isDragAccept ? acceptStyle : {}),
            ...(isDragReject ? rejectStyle : {})
        }),
        [isDragActive, isDragReject]
    );
    const [data, setData] = useState(null);

    const readUploadedFileAsText = acceptedFiles => {
        const temporaryFileReader = new FileReader();
        return new Promise((resolve, reject) => {
            temporaryFileReader.onerror = () => {
                temporaryFileReader.abort();
                reject(new DOMException('Problem parsing input file.'));
            };

            temporaryFileReader.onload = () => {
                resolve(parser.fromSrt(temporaryFileReader.result));
            };
            temporaryFileReader.readAsText(acceptedFiles);
        });
    };

    React.useEffect(() => {
        if (acceptedFiles.length === 1) {
            let file = acceptedFiles[0];
            readUploadedFileAsText(file).then(res => {
                setData({
                    data: res
                });
            });
        }
    }, [acceptedFiles]);


    return (
        <div className='container'>
            <div {...getRootProps({ style })}>
                <input {...getInputProps()} />
                <p>Drag 'n' drop some files here, or click to select files</p>
            </div>
            <File file={data} />
            {console.log(data)}
        </div>
    );
}

07-22 19:03