reactjs - 即使 React.memo 返回 true,子组件也会在父组件时重新渲染
问题描述
我有一个嵌套组件,它启动一个上传图片的 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
吗?
解决方案
从文档:
React.memo 仅检查 prop 更改。如果你封装在 React.memo 中的函数组件在其实现中有一个 useState 或 useContext Hook,它仍然会在状态或上下文发生变化时重新渲染。
在内部,您应该检查您的 isLoading 状态:
useEffect(() => {
...
if(!fileObject.isUploaded && !isLoading) {
setIsLoading(true)
...
}
...
}, [fileObject, isLoading])
推荐阅读
- android - 最近 chrome 更新后 Webview 显示空白页
- matlab - 如何通过白色像素找到两个连接点之间的距离?
- javascript - 如何将 aes 密钥从 js 传输到 java 服务器?
- c - 将指针作为参数传递,内存使用情况
- c - 在 150ns 容差范围内控制 GPIO 引脚
- python - 在python3中单行打印多个字符串的正确方法是什么
- python - 获取文本中名词的性别?
- automata - 我想做一个 CFG,其中字母 b 永远不会三倍
- c# - 从 SQL 脚本重新创建 LINQ 查询的问题
- laravel-5.8 - 部署的 Laravel 项目未运行