我期待状态重新加载道具变化,但这并不工作和用户变量没有更新下useState调用,什么是错误的?

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});
  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

codepen


当前回答

传递给useState的参数是初始状态,就像在类组件的构造函数中设置状态一样,不用于重新呈现时更新状态

如果你想在道具改变时更新状态,请使用useEffect钩子

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});

  React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

演示工作

其他回答

I've seen almost all the answers to this question promoting a bad pattern: updating state as a result of a prop change inside a useEffect call. The useEffect hook is used for synchronizing your React components with external systems. Using it for synchronizing React states can potentially lead to bugs (because re-renders caused by other effects can lead to unintended state updates). A better solution would be to trigger a reconciliation with a key prop change in the <Avatar /> component from its parent:

// App.jsx
function App() {
   // ...logic here
   return <Avatar initialUser={user} key={user.id} />
}

// Avatar.jsx
function Avatar({ initialUser }) {
 // I suppose you need this component to manage it's own state 
 // otherwise you can get rid of this useState altogether.
  const [user, setUser] = React.useState(initialUser);
  return user.avatar ? (
    <img src={user.avatar} />
  ) : (
    <p>Loading...</p>
  );
}

在本例中,您可以将该关键道具视为useEffect的依赖数组,但是由于组件呈现所触发的意外useEffect调用,您将不会触发意外的状态更改。

你可以在这里阅读更多信息: 为国家添加道具

以及更多关于如何useEffect可能是一个脚枪的信息,在这里:

你可能不需要效果

根据ReactJS关于Hooks的文档:

但是如果好友道具在组件出现在屏幕上时发生了变化会发生什么呢?我们的组件将继续显示不同朋友的在线状态。这是一个bug。卸载时还会导致内存泄漏或崩溃,因为取消订阅调用将使用错误的好友ID。

你在这里唯一的互动应该发生在道具的改变上,这似乎不起作用。您可以(仍然根据文档)使用componentDidUpdate(prevProps)来主动捕获对道具的任何更新。

PS:我没有足够的代码来判断,但你不能主动setUser()在你的Avatar(props)函数?

传递给React.useState()的参数只是该状态的初始值。React不会将其识别为改变状态,只会设置其默认值。您首先需要设置默认状态,然后有条件地调用setUser(newValue),它将被识别为一个新状态,然后重新呈现组件。

我建议在没有某种条件的情况下谨慎更新状态,以防止它不断更新,因此每次接收道具时都要重新渲染。您可能想考虑将状态功能提升到父组件,并将父组件的状态作为道具传递给这个Avatar。

传递给useState的参数是初始状态,就像在类组件的构造函数中设置状态一样,不用于重新呈现时更新状态

如果你想在道具改变时更新状态,请使用useEffect钩子

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});

  React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

演示工作

我们使用useState为变量设置初始值的函数组件,如果我们通过props传递初始值,它将始终设置相同的初始值,直到你不使用useEffect钩子,

比如你的案子这个可以帮到你

 React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

传递给useEffect的函数将在渲染提交到屏幕后运行。

默认情况下,效果在每次渲染完成后运行,但您可以选择仅在某些值发生变化时才触发它们。

React.useEffect(FunctionYouWantToRunAfterEveryRender)

如果你只给useEffect传递一个参数,它会在每次渲染后运行这个方法 你可以通过传递第二个参数给useEffect来决定什么时候触发这个函数youwanttorunaftereveryrender

React.useEffect(FunctionYouWantToRunAfterEveryRender, [props.user])

如你所见,我正在传递[道具。现在useEffect只会在道具时触发这个FunctionYouWantToRunAfterEveryRender函数。修改用户

我希望这能帮助你理解 如果需要任何改进,请告诉我,谢谢