繁体   English   中英

为什么这个 React 组件一直在重新渲染?

[英]Why does this React component keep re rendering?

如果用户在 firebase 中输入现有帖子的 ID,我将安装此 Post 组件:

<Route path='/posts/:id' component={Post} />

但是,控制台记录此组件会无限期地发回日志,导致我的浏览器和页面上的操作非常慢。

这是 Post 组件的内容,我认为这与我在 useEffect 中设置 state 的方式有关,但我不确定如何修复它。 我试过 React.Memo 并没有奏效:

function Post(props: RouteComponentProps<PostParams>) {

  const [postData, setPostData] = useState({ title: '', body: '', author: '', time: 0, photoURL: '', likes: 0, dislikes: 0});
  const [existingComments, setExistingComments] = useState([])
  const [commentContent, setCommentContent] = useState('');
  const isMounted = useRef(false);
  const db = fb.firestore();
  const ref = db.doc(`posts/${props.match.params.id}`)

  useEffect(():any => {
    isMounted.current = true;
    ref.get().then((doc: any) => {
      if(doc.exists && isMounted.current) {
        setPostData(doc.data().content);
        setExistingComments(doc.data().comments ? doc.data().comments : [])
      }
    });
    return ()=> isMounted.current = false;
  });

  return ( 
  //... some html that displays the information I've got from firebase

在此先感谢您的帮助:)

When you're updating the state inside useEffect , this triggers a rerender because of the state change and once the component updates, useEffect runs again which changes the state triggering another render cycle, because of this pattern your component keeps rerendering.

您可以添加一个依赖数组来告诉useEffect仅在组件挂载以及某些更改时运行,如下所示:

function Post(props: RouteComponentProps<PostParams>) {

    const [postData, setPostData] = useState({ title: '', body: '', author: '', time: 0, photoURL: '', likes: 0, dislikes: 0 });
    const [existingComments, setExistingComments] = useState([])
    const [commentContent, setCommentContent] = useState('');

    useEffect((): any => {
        const db = fb.firestore();
        const ref = db.doc(`posts/${props.match.params.id}`)
        ref.get().then((doc: any) => {
            if (doc.exists && isMounted.current) {
                setPostData(doc.data().content);
                setExistingComments(doc.data().comments ? doc.data().comments : [])
            }
        });
        return () => { };
    }, [setPostData, setExistingComments]);
    // setPostData, setExistingComments won't get a new reference for every render so they won't cause useEffect to run
    return (<></>);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM