I've started reading about React Hooks and tried to rewrite some small components to use them, but I've got a problem with setting state. Basically, when the child component <Content/> always returns false in shouldComponentUpdate, then parent's (<App/>.setShow) is called, but it does not update the state and <Content/> isn't rendered.
I've prepared a minimal working example below, where <App/> is a component based on React Hoos, and <App2/> is an equivalent class based Component. The latter one works, so apparently there is some nuance there I don't get.
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>