何时使用 useState() 钩子的功能更新形式,例如。 setX(x=>x+1)

发布于 2025-01-11 04:57:56 字数 712 浏览 0 评论 0原文

通常,当我们需要更新功能组件中的状态时,我们会这样做:

function Example() {
    const [count, setCount] = React.useState(0);
    return (<div><p>You clicked {count} times</p>
                 <button onClick={() => setCount(count + 1)}>
                    Click me
                 </button>
            </div>);
}

何时以及为什么需要使用功能更新表单?

function Example() {
    const [count, setCount] = React.useState(0);
    return (<div><p>You clicked {count} times</p>
                 <button onClick={() => setCount(c=>c + 1)}>
                    Click me
                 </button>
            </div>);
}

Normally when we need to update a state in a functional component, we do something like this:

function Example() {
    const [count, setCount] = React.useState(0);
    return (<div><p>You clicked {count} times</p>
                 <button onClick={() => setCount(count + 1)}>
                    Click me
                 </button>
            </div>);
}

When and why will we ever need to use the functional update form?

function Example() {
    const [count, setCount] = React.useState(0);
    return (<div><p>You clicked {count} times</p>
                 <button onClick={() => setCount(c=>c + 1)}>
                    Click me
                 </button>
            </div>);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

不及他 2025-01-18 04:57:56

当 setter 可能会关闭旧的状态值时,请使用函数形式。

例如,如果发起异步请求,并且您希望在完成后更新状态,则发出的请求将具有请求开始时的状态范围,这可能与大多数请求不同。最新的渲染状态。

如果刚刚更新了相同的状态值,您可能还需要使用函数形式,例如

setValue(value + 1);
// complicated logic here
if (someCondition) {
  setValue(value => value + 1);
}

因为setValue的第二次调用关闭了旧的

Use the function form when the setter may close over an old state value.

For example, if an async request is initiated, and you want to update state after that's done, the request that was made will have scope of the state as it was at the beginning of the request, which may not be the same as the most up-to-date render state.

You may also need to use the function form if the same state value was just updated, eg

setValue(value + 1);
// complicated logic here
if (someCondition) {
  setValue(value => value + 1);
}

because the second call of setValue closes over an old value.

毅然前行 2025-01-18 04:57:56

State Updates May Be Asynchronous:

https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

useState is the same as setState in this condition.

遗失的美好 2025-01-18 04:57:56

两次调用 set state 时可以看到不同的情况:

<button
  onClick={() => {
    setCount(count + 1);
    setCount(count + 1);
  }}
></button>;

<button
  onClick={() => {
    setCount(c => (c + 1));
    setCount(c => (c + 1));
  }}
></button>;

You can see the different when call set state twice:

<button
  onClick={() => {
    setCount(count + 1);
    setCount(count + 1);
  }}
></button>;

<button
  onClick={() => {
    setCount(c => (c + 1));
    setCount(c => (c + 1));
  }}
></button>;
脸赞 2025-01-18 04:57:56

还有其他用例。例如,当您在效果内调用 useState 时。如果新状态依赖于旧状态,则可能会导致无限循环。

useEffect(() => {
  setCounter(counter + 1);
}, [counter]);

您可以通过使用功能更新来避免这种情况:

useEffect(() => {
  setCounter(old => old + 1);
}, []);

There are other use cases too. For example, when you call useState inside an effect. If new state is dependent on old state, this might cause an infinite loop.

useEffect(() => {
  setCounter(counter + 1);
}, [counter]);

You can avoid this by using functional updates:

useEffect(() => {
  setCounter(old => old + 1);
}, []);
苍白女子 2025-01-18 04:57:56

功能更新形式还允许将更新函数传递给其子级,同时仍然可以访问父级的状态。

function MyButton(props){
     // return <button onClick={()=>props.onClick(count+1)}>+1</button>;  // error as count is not exposed here
     return <button onClick={()=>props.onClick(n=>(n+1))}>+1</button>;
}
function Example() {
   const [count, setCount] = React.useState(0);
   return (<div><p>Counter: {count}</p>
                <MyButton onClick={setCount}/>
           </div>);
}
ReactDOM.render(<Example/>,document.querySelector("div"));

The functional update form also allows the update function to be passed to its children while still having access to the parent’s state.

function MyButton(props){
     // return <button onClick={()=>props.onClick(count+1)}>+1</button>;  // error as count is not exposed here
     return <button onClick={()=>props.onClick(n=>(n+1))}>+1</button>;
}
function Example() {
   const [count, setCount] = React.useState(0);
   return (<div><p>Counter: {count}</p>
                <MyButton onClick={setCount}/>
           </div>);
}
ReactDOM.render(<Example/>,document.querySelector("div"));
笑叹一世浮沉 2025-01-18 04:57:56

据此:https://reactjs。 org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

功能更新 表单确保您引用的先前状态是可能有最新/最终版本调用多个 setState 挂钩(异步)(例如,如果用户垃圾点击按钮)

并且由于其异步性质,状态不会立即在函数内更新,例如:

func() {
 console.log(counter) // counter = 1
 setCounter(counter => counter + 1) // counter = 1
 console.log(counter) // counter = 1
}

According to this: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

The the functional update form make sure that the previous state that you take reference from is the latest / finalized version when there might be multiple setState hook (which is asynchronous) called (for example, if the user spam click on the button)

And also due to its async nature, the state will not be updated right away within a function, for e.g:

func() {
 console.log(counter) // counter = 1
 setCounter(counter => counter + 1) // counter = 1
 console.log(counter) // counter = 1
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文