如果组件在另一个组件中定义,则在渲染之间丢失状态 [英] Losing state between renders if component is defined in another component

查看:42
本文介绍了如果组件在另一个组件中定义,则在渲染之间丢失状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

codesandbox 在这里:https://codesandbox.io/s/restless-haze-v01wv?file=/src/App.js

我有一个用户组件(简化后)如下所示:

const 用户 = () =>{const [toastOpen, setToastOpen] = useState(false)//处理 toast 关闭的函数返回 (<编辑用户/><吐司/>)}const EditUser = () =>{[user, setUser] = useState(null)useEffect(() => {const fetchedUser = 等待 fetchUser()设置用户(获取用户)}, [])//这种方法会导致用户窗体的用户名在 Toast 关闭时重置const 内容 = () =>{if (user) return 否则返回<div>加载中...</div>}返回<内容/>//如果我这样做,一切都很好返回 (<div>{用户?<UserForm user={user}/>:<div>正在加载...</div>}

)}const UserForm = ({ user }) =>{const [username, setUsername] = useState(user.name)return setUsername(e.target.value)}/>}

在 Toast 仍处于打开状态时查看用户表单页面时,用户表单状态会在 Toast 关闭时重置.

我发现问题出在 EditUser 内部定义的 Content 组件,但我不太清楚为什么会出现这个问题.我很想了解一下 React 引擎盖下正在发生的事情,以及在快乐的道路"中发生的事情

解决方案

你已经在 EditUser 组件中定义了 Content 我们从来没有在 React 组件中做过,因为在这种情况下, Content 将在每次 EditUser重新渲染重新创建.(当然,EditUser 将被重新渲染几次/多次).

因此,重新创建的 Content 组件意味着旧的 Content 将被销毁(卸载)并安装新的 Content.

这就是为什么它被多次挂载并因此重置状态值为初始值.

因此,解决方案是在外部定义它 (Content) - 而不是在任何其他 react 组件内部.

codesandbox here: https://codesandbox.io/s/restless-haze-v01wv?file=/src/App.js

I have a Users component which (when simplified) looks something like this:

const Users = () => {
  const [toastOpen, setToastOpen] = useState(false)

  // functions to handle toast closing
  return (
   <EditUser />
   <Toast />
  )
}

const EditUser = () => {
  [user, setUser] = useState(null)
  useEffect(() => {
    const fetchedUser = await fetchUser()
    setUser(fetchedUser)
  }, [])

  // this approach results in UserForm's username resetting when the toast closes
  const Content = () => {
    if (user) return <UserForm user={user} />
    else return <div>Loading...</div>
  }
  return <Content />

  // if I do this instead, everything's fine
  return (
    <div>
    {
      user ? <UserForm user={user} /> : <div>Loading...</div>
    }
    </div>
  )
}

const UserForm = ({ user }) => {
  const [username, setUsername] = useState(user.name)

  return <input value={username}, onChange={e => setUsername(e.target.value)} />
}

While viewing the UserForm page while a Toast is still open, the UserForm state is reset when the Toast closes.

I've figured out that the issue is the Content component defined inside of EditUser, but I'm not quite clear on why this is an issue. I'd love a walkthrough of what's happening under React's hood here, and what happens in a "happy path"

解决方案

You have defined Content inside EditUser component which we never do with React Components, because in this situtaion, Content will be re-created every time the EditUser is re-rendered. (surely, EditUser is going to be re-rendered few/many times).

So, a re-created Content component means the old Content will be destroyed (unmounted) and the new Content will be mounted.

That's why it is be being mounted many times and hence resetting the state values to initial values.

So, the solution is to just define it (Content) outside - not inside any other react component.

这篇关于如果组件在另一个组件中定义,则在渲染之间丢失状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆