当前位置: 首页 > 面试题库 >

为什么'useState'钩子在引用函数时会调用初始状态?

阎自怡
2023-03-14
问题内容

React有一个叫做useState的钩子,在向功能组件html" target="_blank">添加状态时使用。

该挂钩API参考状态:

useState

const [state, setState] = useState(initialState);

返回一个有状态值,以及一个更新它的函数。

在初始渲染期间,返回的状态(state)与作为第一个参数(initialState)传递的值相同。

setState功能用于更新状态。它接受一个新的状态值并排队重新呈现组件。

该阵营文档状态:

useState 作为论点我们要传递什么?

useState()挂钩的唯一参数是初始状态。与类不同,状态不必是对象。如果需要,我们可以保留一个数字或一个字符串。在我们的示例中,我们只需要一个用户点击次数的数字,因此将0变量作为初始状态传递。(如果要在状态中存储两个不同的值,则将调用useState()两次。)

意外行为:

但是,我注意到一些奇怪的, 看似没有记载的 行为。

如果我尝试使用useState挂钩将函数存储为状态,则 react将调用函数reference 。例如

const arbitraryFunction = () => {
    console.log("I have been invoked!");
    return 100;
};

const MyComponent = () => {

    // Trying to store a string - works as expected:
    const [website, setWebsite] = useState("stackoverflow"); // Stores the string
    console.log(typeof website);                             // Prints "string"
    console.log(website);                                    // Prints "stackoverflow"

    // Trying to store a function - doesn't work as expected:
    const [fn, setFn] = useState(arbitraryFunction);         // Prints "I have been invoked!"
    console.log(typeof fn);                                  // Prints "number" (expecting "function")
    console.log(fn);                                         // Prints "100"

    return null; // Don't need to render anything for this example...
};

当我们调用时useState(arbitraryFunction),react将调用arbitraryFunction并将其返回值用作状态。

解决方法:

通过将函数引用包装在另一个函数中,我们可以将函数存储为状态。例如

const [fn, setFn] = useState(() => arbitraryFunction)

我还没有遇到任何将函数存储为状态的现实原因,但是似乎有人奇怪地做出了明确选择以不同方式对待函数参数的选择。

这个选择可以在整个React代码库的多个地方看到:

initialState = typeof initialArg === 'function' ? initialArg() : initialArg;

为什么此看似未记录的功能存在?

我想不出为什么有人希望/期望调用他们的函数引用的任何充分理由,但是也许可以。

如果记录在案,在哪里记录?


问题答案:

这是记录在这里:

懒惰的初始状态

initialState参数是初始渲染期间使用的状态。在后续渲染中,将忽略它。如果初始状态是昂贵的计算结果,则可以提供一个函数,该函数将仅在初始渲染器上执行:

const [state, setState] = useState(() => {
  const initialState = someExpensiveComputation(props);
  return initialState;
});

将回调传递给setState 也会调用该回调,但是出于不同的原因:

功能更新

如果使用先前状态计算新状态,则可以将函数传递给setState。该函数将接收先前的值,并返回更新的值。这是使用两种形式的setState的计数器组件的示例:

>     function Counter({initialCount}) {
>       const [count, setCount] = useState(initialCount);
>       return (
>         <>
>           Count: {count}
>           <button onClick={() => setCount(initialCount)}>Reset</button>
>           <button onClick={() => setCount(prevCount => prevCount -
> 1)}>-</button>
>           <button onClick={() => setCount(prevCount => prevCount +
> 1)}>+</button>
>         </>
>       );
>     }


 类似资料:
  • 在本例中,我仅使用初始值设定项函数调用: 从控制台中可以看到,函数被调用了两次。这是正常的行为,有什么原因吗?

  • 问题内容: 我仍然不停地做出反应,但仍在努力查看我在做什么错。我有一个用于调整面板大小的组件,边缘的onmousedown会更新状态的值,然后有一个用于mousemove的事件处理程序,该事件处理程序使用此值,但是在值更改后似乎没有更新。 这是我的代码: 问题出在函数上,应该使用的是字符串的最新版本,而实际上是。 问题答案: 当前,您的问题是您正在读取过去的价值。当您定义它属于该渲染时,因此,在重

  • 以下是现场演示:https://codesandbox.io/s/strange-bash-qj7ld?file=/src/App.js 所以我有一个这样的组件 每次单击按钮时,计数器都会增加,组件将重新渲染。然后将再次调用,然后它将返回一个数组。当发生变化时,会触发。我有两个问题: 为什么只触发一次,而不是每次后续调用?非原语是一个数组,它是一个非原语类型,所以它应该每次都不同,即使它里面的字符

  • 我第一次面对的问题很小。我试图使用一个简单的useState,但出于某种原因,我不明白为什么React会给我一个错误,不管我想做什么--没有什么能修复它。 这是错误的图像:错误描述: 错误:无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一:1.React和呈现器(例如React DOM)2的版本可能不匹配。你可能违反了钩子3的规则。在同一个应用程序中可能有多个React副

  • 问题内容: 假设我希望能够在程序中任何地方每次引发异常时都能够记录到文件。我不想修改任何现有代码。 当然,可以将其概括为每次引发异常时都可以插入钩子。 以下代码是否被认为可以安全地执行此操作? 问题答案: 如果要记录 未捕获的 异常,只需使用sys.excepthook即可。 我不确定是否会记录 所有 引发的异常的价值,因为很多库会在内部为可能不关心的事情引发/捕获异常。

  • 我正在构建一个制表符视图,我不明白为什么useState钩子没有更新我的状态。我肯定这是件容易的事,但我在这里已经被难住了一段时间... 我可以看到onPress函数已启动,如果我注销,则item.label是正确的。但是,即使我硬编码参数,setState也不会更改。