对于如何从一个useEffect看起来相当错误的钩子中触发一些实际事件(并且无论如何都会导致不当行为),我的反应和困难都是很新的。
有什么最好的做法吗?或者说使用钩子是个坏主意?
这是一个非常粗糙的文件选择器示例。主要要求是,如果文件无效,processFile应该触发一次警报。
import { ChangeEvent, useEffect, useState } from 'react';
export const useUploader = () => {
const [file, setFile] = useState<File | undefined>();
const [isInvalid, setIsInvalid] = useState(false);
const processFile = (inputfile: File) => {
const fileTooBig = inputfile.size > 1 * 1024 * 1024;
setFile(fileTooBig ? undefined : inputfile);
setIsInvalid(fileTooBig);
if (fileTooBig) {
// trigger event?
}
};
return { file, isInvalid, processFile };
};export const ImageUpload = () => {
const { file, isInvalid, processFile } = useUploader();
const { t } = useTranslation();
// "Wrong appraoch" as it would also show the alert when
// translation changes or a hot-reload happens during development
useEffect(() => {
if (isInvalid) {
alert(t('Invalid file selected'));
}
}, [isInvalid, t]);
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
if (e.currentTarget.files) {
processFile(e.currentTarget.files[0]);
}
};
return (
<>
<input type="file" onChange={onChange}></input>
<span>Selected file: {file?.name}</span>
<span>IsInvalid: {isInvalid ? 'Invalid' : 'All fine'}</span>
</>
);
};发布于 2022-03-17 14:58:39
您只需使用一个状态来表示无效状态。
import { ChangeEvent, useEffect, useState } from 'react';
export const useUploader = () => {
/**
* one could use three states here
*
* undefined means the empty state
* null means an error state
* file means success state
*/
const [file, setFile] = useState<File | undefined>();
const processFile = (inputfile: File) => {
const fileTooBig = inputfile.size > 1 * 1024 * 1024;
setFile(fileTooBig ? null : inputfile);
};
const isInvalid = file === null;
return { file, isInvalid, processFile };
};
export const ImageUpload = () => {
const { file, isInvalid, processFile } = useUploader();
/**
* this is just, okay.
*/
useEffect(() => {
if (isInvalid) {
alert('Invalid file selected');
}
}, [isInvalid]);
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
if (e.currentTarget.files) {
processFile(e.currentTarget.files[0]);
}
};
return (
<>
<input type="file" onChange={onChange}></input>
<span>Selected file: {file?.name}</span>
<span>IsInvalid: {isInvalid ? 'Invalid' : 'All fine'}</span>
</>
);
};https://stackoverflow.com/questions/71514350
复制相似问题