我正在重构以使用Hooks,我遇到了一个非常令人困惑的墙
我有一个基本的功能组件:
export const MakeComponent = props => {
const { path, value, info, update } = props;
const [val, setVal] = useState(value);
console.log(value, val); // abc undefined
return (...)
}
日志返回abc undefined
,即props中的value
是明确定义的,但从useState(value)
返回的第一个参数是undefined
为了测试钩子是否工作,我尝试了useState("abc")
,并按预期记录了abc
。
我不知道我做错了什么——有什么想法吗?
React版本:16.8.6
编辑这里是父组件-就我所见,这里没有什么新奇的事情!
<MakeComponent
path={key}
value={item[key]}
info={value}
update={updateDiffs}
/>
正如注释中所暗示的,useState(initialState)
(或您所称的任何名称(将仅在第一次渲染时使用initialState
。
在初始渲染期间,返回的状态(
state
(与作为第一个参数传递的值(initialState
(相同。
(React Docs,emphasis mine(
之后,在重新渲染时,useState函数不会根据传入的道具的新更改来更改状态。
要在每次value
更改时反映更改,请在输入道具上注册一个效果,如
export const MakeComponent = props => {
const { path, value, info, update } = props;
const [val, setVal] = useState(value);
useEffect(() => { setVal(value)}, [value] )
return (...)
}
注意,仅仅根据道具的变化来设置状态有点反模式,因为MonsterBucket注意到,你可以直接依靠道具的变化触发重新渲染:
export const MakeComponent = props => {
const { path, value, info, update } = props;
const [val, setVal] = useState(value);
if (val !== value) { // don't update unnecessarily
setVal(value);
}
return (...)
}
相反,将useEffect保留为侧效果,主要是React渲染循环之外的效果。
要查看这些示例,请查看这些ReactJs文档-您可能不需要效果,它涵盖了许多其他示例。
如果你想更新道具更改的状态,你必须添加useEffect
,它会监听道具更改&将相应地更新状态值
这是更新的片段
export const MakeComponent = props => {
const { path, value, info, update } = props;
const [val, setVal] = useState(value);
useEffect(() => { setVal(value)}, [value] )
return (<div>{val}</div>)
}
正在处理沙盒链接
https://codesandbox.io/s/confident-agnesi-ohkq7?file=/src/MakeComponent.js
当您将道具value
传递给useState
时,其值可能尚未设置。CCD_ 16本身可能已经是CCD_。
此外,setState
并不是真正的同步,所以如果useState
使用与setState
相同的机制,则状态val
可能还没有设置为value
作为初始值。
在这种情况下,使用props作为状态的初始值,应该使用没有依赖关系的side效果。第一次渲染完成后,效果将运行并使用道具设置状态。您可以让组件的初始值未定义,不传递任何内容而不会出现任何问题。
export const MakeComponent = props => {
const { path, value, info, update } = props;
const [val, setVal] = useState();
// get initial state after initial render
useEffect(() => {
setVal(value)
}, [])
console.log(value, val); // abc undefined then will log abc abc
return (...)
}
请记住,React中的props是只读的,state用于读写。但是,如果你只使用道具作为状态的初始值,并在那之后使用道具而不是道具设置的状态,这是非常好的,不,也不是反模式。这是为了保持一致性,因为在某种情况下,道具和状态一次可能有两个不同的值。
您的案例可能需要在任意时间关心道具的价值,这取决于您的需求,正如上面的一个答案所强调的那样。你的问题没有说明这一点。尽管如此,如果是这样,您可以将道具添加到使用该道具设置状态的效果的依赖数组中,并且可以为您想要相同效果的其他道具编写单独的效果。
如果你不需要为这些数据写作,你根本不需要那个模式,只要使用prop,它就会是最新的,你就会有一致性。但你显然是这样做的,我希望我上面建议的模式对你和我一样有效