I am trying to optimize my React list rendering using the React memo feature of manual props comparison. I have generated a list of simple "toggle" buttons:
import React, { useState } from "react";
import "./styles.css";
import { Toggle } from "./Toggle";
export default function App() {
const [list, setList] = useState({ a: true, b: true, c: true });
const handleClick = x => {
console.log(list);
const currentValue = list[x];
setList({ ...list, [x]: !currentValue });
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{Object.keys(list).map(x => (
<Toggle key={x} isChecked={list[x]} name={x} onChange={handleClick} />
))}
</div>
);
}
This is the "toggle" button:
import React from "react";
const areEqual = (prevProps, nextProps) => {
return prevProps.isChecked === nextProps.isChecked;
};
const ToggleComponent = ({ isChecked, name, onChange }) => {
return (
<>
<h1>{isChecked ? "This is true" : "This is false"}</h1>
<button onClick={() => onChange(name)}>{name}</button>
</>
);
};
export const Toggle = React.memo(ToggleComponent, areEqual);
My issue is that the list object actually doesn't store the expected value. Every time I click on the buttons I get the same, default one { a: true, b: true, c: true }
(it is visible in the console.log
of handleClick
), but if I delete the areEqual
function, everything works properly again and the list object is updated as it should be.
EDIT:
I saw that if I change the whole thing into an array and wrap every button into an object, the memo feature works as intended.