代码之家  ›  专栏  ›  技术社区  ›  Nish

太多的重新渲染,无限的重新渲染

  •  0
  • Nish  · 技术社区  · 3 年前

    为什么当我调用 setPost 使用 usePost hook 来自父组件(Post)?错误的原因是什么?

    function Post({ activePostId }) {
      const { status, post, setPost, error, refetch } = usePost(activePostId)
      const [savePost, savePostStatus] = useSavePost()
    
      setPost('SetPost')
    
      const onSubmit = async (values) => {
        try {
          await savePost(values)
          refetch()
        } catch (err) {
          console.error(err)
        }
      }
    
    export default function usePost(postId) {
      const [post, setPost] = React.useState()
      const [error, setError] = React.useState()
      const [status, setStatus] = React.useState('loading')
    
      const refetch = async () => {
        try {
          setStatus('loading')
    
          const post = await axios
            .get(`/api/posts/${postId}`)
            .then((res) => res.data)
    
          setPost(post)
          setError()
          setStatus('success')
        } catch (err) {
          setError(err)
          setStatus('error')
        }
      }
    
      React.useEffect(() => {
        refetch()
      }, [])
    
      return {
        post,
        setPost,
        status,
        error,
        refetch,
      }
    }
    
    
    0 回复  |  直到 3 年前
        1
  •  0
  •   nipuna777    3 年前

    setPost 改变 post 钩子中的值,该值由组件消耗。这会触发重新渲染,从而导致无限循环。

    要解决这个问题,你需要打电话 路标 只有有限的次数。你可以通过使用 useEffect 只能在启动时调用。

    function Post({ activePostId }) {
      const { status, post, setPost, error, refetch } = usePost(activePostId)
      const [savePost, savePostStatus] = useSavePost()
    
      useEffect(() => {
        setPost('SetPost')
      }, []); // <- the empty array here ensures that the setPost is called once, if you want it called on other dependency changes, you can add them here.
      
      const onSubmit = async (values) => {
        try {
          await savePost(values)
          refetch()
        } catch (err) {
          console.error(err)
        }
      }