我有一个嵌套的组件,它发起一个上传图像的HTTP请求。它显示进度。
const PreviewItem = React.memo(function PreviewItem(props: PreviewItemProps) {
    const {fileObject, handleRemove, classes, onUploadFinished} = props
    const [isLoading, setIsLoading] = useState(false)
    const [completed, setCompleted] = useState(0);
    const cancelTokenSource = axios.CancelToken.source();
    useEffect(() => {
        const data = new FormData();
        data.append('file', fileObject.file);
        const config: AxiosRequestConfig = {
            onUploadProgress: function (progressEvent) {
                const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
                setCompleted(percentCompleted)
            },
            cancelToken: cancelTokenSource.token
        };
        if (!fileObject.isUploaded) {
            setIsLoading(true)
            avantiApi.post<DirectUploadResponse>("images/upload", data, config).then(response => {
                setIsLoading(false)
                if (onUploadFinished) {
                    onUploadFinished(response.data, fileObject)
                }
            }).catch(e => console.log("Upload Error", e))
        }
        return function abortUpload() {
            console.log("Use effect...aborting...")
            cancelTokenSource.cancel("Cancelled")
        }
    }, [fileObject])
    return <> ..... </>
}, function (prevProps: Readonly<PropsWithChildren<PreviewItemProps>>, nextProps: Readonly<PropsWithChildren<PreviewItemProps>>) {
    const areEqual = prevProps.fileObject === nextProps.fileObject
    console.log("Are equal?", areEqual)
    return areEqual
})我的问题是,即使React.memo的propsAreEqual函数返回true,组件也会在上传图像时进行重新渲染-如果父组件进行了重新渲染-并请求重新启动。我是不是遗漏了React.memo的用法
发布于 2020-11-25 03:31:12
从docs
React.memo仅检查属性更改。如果包装在React.memo中的函数组件在其实现中具有useState或useContext钩子,那么当状态或上下文发生变化时,它仍然会重新呈现。
在内部,你应该检查你的isLoading状态:
useEffect(() => {
  ...
  if(!fileObject.isUploaded && !isLoading) {
    setIsLoading(true)
    ...
  }
  ...
}, [fileObject, isLoading])发布于 2020-11-25 03:16:20
我建议更改为:
}, function (prevProps: Readonly<PropsWithChildren<PreviewItemProps>>, nextProps: Readonly<PropsWithChildren<PreviewItemProps>>) {
    const areEqual = JSON.parse(prevProps.fileObject) === JSON.parse(nextProps.fileObject)
    console.log("Are equal?", areEqual);
    return areEqual;
})为了确保乳清真的平等,也许这就是问题所在。
https://stackoverflow.com/questions/64993321
复制相似问题