reactjs - 当 child.shouldComponentUpdate() 返回 false 时,React useState() 钩子(Hook)不会更新状态

标签 reactjs react-hooks

我已经开始阅读 React Hooks 并尝试重写一些小组件以使用它们,但我在设置状态时遇到了问题。基本上,当子组件 <Content/>总是返回 falseshouldComponentUpdate ,然后调用父级的 ( <App/>.setShow ),但它不会更新状态和 <Content/>未呈现。

我在下面准备了一个最小的工作示例,其中 <App/>是一个基于 React Hoos 的组件,<App2/>是一个等效的基于类的组件。后者有效,所以显然有一些我不明白的细微差别。

const {useState} = React;

class Panel extends React.Component {
   shouldComponentUpdate() { return false; } 
   render() { return (<button onClick={this.props.onClick}>Toggle</button>) }
}

class Content extends React.Component {
  render() { return <div>Content</div> }
}

const App = (props) => {
  const [show, setShow] = useState(true);

  const toggle = () => {
    console.log("Toggling visibility!", show);
    setShow(!show);
  }

  console.log("[App] render()");
  return (<div >
    <h1>Hi at {Date.now()}</h1>
    <Panel onClick={toggle} />
    {show && <Content /> }
  </div>)
}

class App2 extends React.Component {
  state = { show: true }

  render() {
    const toggle = () => {
      console.log("[App] toggle", this.state.show)
      this.setState({ show: !this.state.show })
    }

    console.log("[App] render()");
    return (<div >
      <h1>Hi at {Date.now()}</h1>
      <Panel onClick={toggle} />
      {this.state.show && <Content />}
    </div>)
  }
}

ReactDOM.render(<div> <App/> <App2/> </div>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

<div id="app">
</app>

最佳答案

您需要使用 functional updates因为你有 closure toggle 函数中 show 的值。

关闭发生是因为 shouldComponentUpdate 总是返回 false,所以在第一次渲染 this.props.onClick 的值时会有过时的状态show === true,在后续渲染中不会改变。

const App = () => {
  const [show, setShow] = useState(true);

  // Closure on value of show
  // const toggle = () => {
  //   console.log("Toggling visibility!", show);
  //   setShow(!show);
  // }

  const toggle = () => {
    setShow(prevState => {
      console.log("Toggling visibility!", prevState);
      return !prevState;
    });
  };

  console.log("[App] render()");
  return (
    <div>
      <h1>Hi at {Date.now()}</h1>
      <Panel onClick={toggle} />
      {show && <Content />}
    </div>
  );
};

Edit gallant-saha-9z8eu

关于reactjs - 当 child.shouldComponentUpdate() 返回 false 时,React useState() 钩子(Hook)不会更新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62743490/

相关文章:

reactjs - 如何通过输入 ReactJS 中的单词进行检测

javascript - 在useEffect中设置状态完成后如何调用函数?

reactjs - 在 React 中使用 memoized 回调,同时使用 .map 创建多个组件

reactjs - 如何在 React Native 中从孙子到祖 parent 进行通信,然后再返回到祖 parent 的 child

reactjs - 如何在useEffect Hook 中仅观看对象中的单个字段?

reactjs - 无法使用react-create-app将我的应用程序部署到github页面

javascript - React JSX,如何用单引号渲染文本?例子<p>我</p>

javascript - 在没有 setTimeout 的情况下在 componentDidMount() 中操作 DOM

reactjs - 如何使用react和material-ui让一个元素滑入而另一个元素滑出?

javascript - 我们在 React 中使用哪些钩子(Hook)来更新和删除?