简体   繁体   English

在 React 钩子中切换 object state 中的值的正确方法是什么?

[英]What is the right way to toggle a value inside object state in React hooks?

Here is a simple code sample to toggle a button这是一个切换按钮的简单代码示例

import React, { useState } from "react";
import "./styles.css";

const initialState = {
  isOpen: true
};

export default function App() {
  const [state, _setState] = useState(initialState);
  const setState = newState =>
    _setState(prevState => ({ ...prevState, ...newState }));

  const toggleButton = () => {
    setState({ isOpen: !state.isOpen });
  };

  return (
    <div className="App">
      <button onClick={toggleButton}>Show</button>
      {state.isOpen && <h1>Hello World</h1>}
    </div>
  );
}

Questions问题

  1. Is the above code is the right way to toggle a value inside an object?上面的代码是在 object 中切换值的正确方法吗?
  2. Is there any advantage if I change the toggleButton function to code below?如果我将toggleButton function 更改为下面的代码,有什么好处吗? By not accessing state object reference when setState executes.通过在setState执行时不访问state object 引用。
const toggleButton = () => {
    const { isOpen } = state;
    setState({ isOpen: !isOpen });
};

Questions问题

  1. Is the above code is the right way to toggle a value inside an object?上面的代码是在 object 中切换值的正确方法吗?

This is maybe debatable, but the correct way to toggle any react state is to use a functional state update.可能值得商榷,但切换任何反应 state 的正确方法是使用功能性 state 更新。 This is because multiple state updates can be enqueued and batch processed.这是因为可以对多个 state 更新进行排队和批处理。 You want them to process in the order in which they are queued and end with the correct state.您希望它们按照它们排队的顺序进行处理,并以正确的 state 结束。

const toggleButton = () => {
  setState(prevState => ({ isOpen: !prevState.isOpen }));
};

The following is a demo I use to demonstrate why functional updates work.以下是我用来演示功能更新为何起作用的演示。

编辑反应 - 定期和功能状态更新

  1. Is there any advantage if I change the toggleButton function to code below?如果我将 toggleButton function 更改为下面的代码,有什么好处吗? By not accessing state object reference when setState executes.通过在 setState 执行时不访问 state object 引用。
 const toggleButton = () => { const { isOpen } = state; setState({ isOpen: ;isOpen }); };

No, not really, it's still directly accessing the current state object that is enclosed in the callback function scope.不,不是真的,它仍然直接访问当前 state object 包含在回调 function Z31A181FD140BECA185D 中

Since React may batch multiple setState() calls into a single update for performance, it is better to get the previous state than accessing it directly由于 React 可能将多个 setState() 调用批处理到单个更新中以提高性能,因此最好获取之前的 state 而不是直接访问它

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

This would be the correct form of doing it这将是这样做的正确形式

setState(prevState => ({
  isOpen: !prevState.isOpen
}));

with Hooks you could do this:使用 Hooks 你可以这样做:

 import React, { useState } from "react"; import "./styles.css"; export default function App() { const [isOpen, useIsOpen] = useState(false); const toggleButton = () => { useIsOpen((prevState) => { return {isOpen: .prevState;isOpen}; }) } return ( <div className="App"> <button onClick={toggleButton}>Show</button> </div> ); }

or alternatively you could:或者你可以:

 export default function App() { const [isOpen, useIsOpen] = useState(false); const toggleButton = () => useIsOpen(;isOpen); return ( <div className="App"> <button onClick={toggleButton}>Show</button> </div> ); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM