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