I´m learning React and i found that React.memo() "is not working", because my component again re-render on every update that i do on the parent class-based component. But the problem is that props on component don´t change, at least it make sense for me
I used useEffect hook to print on my screen that re-render, although i use React.memo(Men)
const Men = props => {
useEffect(() => {
console.log("rendered");
});
return <p onClick={props.add}>{props.adder}</p>;
};
React.memo(Men);
class App extends React.Component {
state = {
counter: 0,
adder: "press"
};
add = () => {
this.setState(prevState => {
return {
counter: prevState.counter + 1
};
});
};
render() {
return (
<div className="App">
<p>{this.state.counter}</p>
<Men adder={this.state.adder} add={this.add} />
</div>
);
}
}
I expect that in my console the message 'rendered' inside the useEffect hook appears only once time.
This is happening due to how you are using memo
- you need to use the return value that React.memo(Men)
gives you.
Like this:
This CodePen will cause a re-render
This CodePen will NOT cause a re-render
Correct:
const MenBefore = props => {
React.useEffect(() => {
console.log("rendered");
});
return <p onClick={props.add}>{props.adder}</p>;
};
////////////////////////////////////////
const Men = React.memo(MenBefore); // <--- THIS LINE
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class App extends React.Component {
state = {
counter: 0,
adder: "Click Me - I will -NOT- cause a re-render"
};
add = _ => {
this.setState(prevState => {
return {
counter: prevState.counter + 1
};
});
};
render() {
return (
<div className="App">
<p>{this.state.counter}</p>
<Men adder={this.state.adder} add={this.add} />
</div>
);
}
}
ReactDOM.render(<App />, document.body);
Incorrect:
const Men = props => {
React.useEffect(() => {
console.log("rendered");
});
return <p onClick={props.add}>{props.adder}</p>;
};
/////////////////////////////
React.memo(Men); // <<<--------- WRONG
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
class App extends React.Component {
state = {
counter: 0,
adder: "Click Me - I will cause a re-render"
};
add = _ => {
this.setState(prevState => {
return {
counter: prevState.counter + 1
};
});
};
render() {
return (
<div className="App">
<p>{this.state.counter}</p>
<Men adder={this.state.adder} add={this.add} />
</div>
);
}
}
ReactDOM.render(<App />, document.body);