Javascript 如何使用依赖项一个接一个地运行2个setState钩子?

Javascript 如何使用依赖项一个接一个地运行2个setState钩子?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我刚刚开始使用钩子,在useEffect回调中出现了这种情况。我想运行以下两个setState命令,第一个命令将设置某人的年数,第二个命令将使用此年值设置他们的月数 这是一个奇怪的例子,但我基本上想知道,一旦第一个设置了年数的值,如何运行第二个setState React.useEffect(() => { if (personExists) { setYears(getPerson(person.name, person.dob)); setMonths(getM

我刚刚开始使用钩子,在useEffect回调中出现了这种情况。我想运行以下两个setState命令,第一个命令将设置某人的年数,第二个命令将使用此年值设置他们的月数

这是一个奇怪的例子,但我基本上想知道,一旦第一个设置了年数的值,如何运行第二个setState

React.useEffect(() => {
    if (personExists) {
    setYears(getPerson(person.name, person.dob));
    setMonths(getMonths(person.name, years);
}
}, [person]);

您已经清楚地注意到状态是异步的,并且您可以使用原始代码读取旧的状态

只需先“本地”进行计算,然后将值设置为状态

const newYears = getYears(person.name, person.dob);
const newMonths = getMonths(person.name, newYears);
setYears(newYears);
setMonths(newMonths);
另一种选择是使用
useffect
使计算
月数
成为
年数
变化的副作用,但这将更难解释

同样值得考虑的是,如果用户不可修改,这里的
是否应该处于状态;您可以改为使用已记忆的值:

const [years, months] = React.useMemo(() => {
  const years = getYears(person.name, person.dob);
  const months = getMonths(person.name, years);
  return [years, months];
}, [person]);

您可以将其拆分为两个useEffect,这样在年更改后调用setMonths。我也喜欢@AKZ的第二种方法

React.useEffect(() => {
    if (personExists) {
     setYears(getPerson(person.name, person.dob));
    }
}, [person]);

React.useEffect(() => {
    if (personExists) {
     setMonths(getMonths(person.name, years);
    }
}, [years]);

啊,好的,我想知道是否有一些特定的React约定或最佳实践来处理相互依赖的多个setState命令。那么在您的示例中,首先计算出值,然后运行setState?是否有可能顺序被弄乱,而“未定义”被存储在状态中?不,如果所有涉及的函数都是同步的(除了宇宙射线弄乱CPU的指令指针使其跳过代码行;-),则不可能发生这种情况。在组件的下一次渲染期间,
都将根据请求进行更改(除非在下一次渲染之前有其他更改)。哈,我不确定第二个示例是什么,我不知道useMemo是如何工作的。你更喜欢哪种方法,我不知道你这里所说的记忆值是什么意思。这是我第一次在应用程序中设置这些值,然后使用它们在流的不同部分呈现UI。如果用户无法手动设置这些值,并且您可以始终从其他数据(在本例中为
person.name
person.dob
)派生这些值,则它们不应处于任何状态。请参见此处关于useMemo:因此,值来自用户可以返回并修改的表单,我认为使用状态是最好的方法,但我不确定。