我希望在道具更改时重新加载状态,但这不起作用,并且在下一次user
调用中useState
变量不会更新,这是怎么回事?
function Avatar(props) {
const [user, setUser] = React.useState({...props.user});
return user.avatar ?
(<img src={user.avatar}/>)
: (<p>Loading...</p>);
}
答案 0 :(得分:17)
传递给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>);
}
答案 1 :(得分:2)
使用useState
为变量设置初始值的功能组件,如果我们通过prop传递初始值,它将始终设置相同的初始值,直到您不使用useEffect
钩子为止,
例如您的情况,这将完成您的工作
React.useEffect(() => {
setUser(props.user);
}, [props.user])
传递给useEffect的函数将在将渲染提交到屏幕后运行。
默认情况下,效果会在每个完成的渲染之后运行,但是您可以选择仅在某些值更改后才触发效果。
React.useEffect(FunctionYouWantToRunAfterEveryRender)
如果仅将一个参数传递给useEffect,则它将在每次渲染后运行此方法 您可以通过将第二个参数传递给useEffect
来决定何时触发此FunctionYouWantToRunAfterEveryRender
React.useEffect(FunctionYouWantToRunAfterEveryRender, [props.user])
您注意到我现在正在传递[props.user],useEffect
仅在更改FunctionYouWantToRunAfterEveryRender
时才会触发此props.user
函数
我希望这可以帮助您理解 让我知道是否需要任何改进
答案 2 :(得分:1)
我已经创建了这样的自定义钩子:
app.append(`<span>${anyValue}</span>`);
使用:
const usePrevious = value => {
const ref = React.useRef();
React.useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
const usePropState = datas => {
const [dataset, setDataset] = useState(datas);
const prevDatas = usePrevious(datas);
const handleChangeDataset = data => setDataset(data);
React.useEffect(() => {
if (!deepEqual(datas, prevDatas)) // deepEqual is my function to compare object/array using deep-equal
setDataset(datas);
}, [datas, prevDatas]);
return [
dataset,
handleChangeDataset
]
}
答案 3 :(得分:1)
您可以为此创建自己的自定义简单钩子。钩子在更改时更改了默认值。
https://gist.github.com/mahmut-gundogdu/193ad830be31807ee4e232a05aeec1d8
import {useEffect, useState} from 'react';
export function useStateWithDep(defaultValue: any) {
const [value, setValue] = useState(defaultValue);
useEffect(() => {
setValue(defaultValue);
}, [defaultValue]);
return [value, setValue];
}
// 示例
// const [user, setUser] = useStateWithDep(props.user);
答案 4 :(得分:0)
根据ReactJS documentation about Hooks:
但是,如果在屏幕上显示组件时好友道具发生了变化,该怎么办?我们的组件将继续显示其他朋友的在线状态。这是一个错误。卸载时,由于取消订阅调用会使用错误的朋友ID,因此也会导致内存泄漏或崩溃。
您唯一的互动应该在道具更改时进行,这似乎不起作用。您可以(仍然根据文档)使用componentDidUpdate(prevProps)来主动捕获对道具的任何更新。
PS:我没有足够的代码来判断,但是您不能在Avatar(props)函数内部积极设置setUser()吗?
答案 5 :(得分:0)
传递给React.useState()
的参数只是该状态的初始值。 React不会将状态更改为更改,仅设置其默认值即可。您将需要先设置默认状态,然后有条件地调用setUser(newValue)
(它将被识别为新状态),然后重新呈现组件。
我建议在没有某种条件的情况下谨慎更新状态,以防止其不断更新,因此,每次接收到道具时都要重新渲染。您可能需要考虑将状态功能提升到父组件,并将父状态作为道具传递给此头像。
答案 6 :(得分:-1)
在反应世界中,在这种情况下,您应该在componentWillRecieveProps(nextProps)函数中更新状态。