首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >即使React.memo返回true,父组件也会重新呈现子组件

即使React.memo返回true,父组件也会重新呈现子组件
EN

Stack Overflow用户
提问于 2020-11-25 03:13:00
回答 2查看 447关注 0票数 4

我有一个嵌套的组件,它发起一个上传图像的HTTP请求。它显示进度。

代码语言:javascript
运行
复制
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的用法

EN

回答 2

Stack Overflow用户

发布于 2020-11-25 03:31:12

docs

React.memo仅检查属性更改。如果包装在React.memo中的函数组件在其实现中具有useState或useContext钩子,那么当状态或上下文发生变化时,它仍然会重新呈现。

在内部,你应该检查你的isLoading状态:

代码语言:javascript
运行
复制
useEffect(() => {
  ...
  if(!fileObject.isUploaded && !isLoading) {
    setIsLoading(true)
    ...
  }
  ...
}, [fileObject, isLoading])
票数 1
EN

Stack Overflow用户

发布于 2020-11-25 03:16:20

我建议更改为:

代码语言:javascript
运行
复制
}, 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;
})

为了确保乳清真的平等,也许这就是问题所在。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64993321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档