Reputation: 6884
I have a TodosList
component that renders a list of Todo
components.
Here is the Todo component:
export class Todo extends React.PureComponent {
render() {
return (
<li onClick={this.props.onClick}>
{this.props.title}
</li>
);
}
}
Here is the TodoList component:
export class TodoList extends React.PureComponent {
toggleTodo = id => this.props.toggleTodo(id);
constructor(props) {
super(props);
}
render() {
return (
<ul>
{this.props.todos.map(todo => (
<Todo
key={todo.id}
{...todo}
onClick={this.toggleTodo.bind(null, todo.id)}
/>
))}
</ul>
);
}
}
The problem with the code is that bind creates a new function which will cause the pure component to re-render even if nothing has changed.
How can I solve this?
A solution can be something like this:
export class Todo extends React.PureComponent {
render() {
return (
<li onClick={this.props.onClick.bind(null, this.props.id)}>
{this.props.title}
</li>
);
}
}
But I'm wondering if this is a good solution.
Upvotes: 0
Views: 907
Reputation: 3004
You should pass only the reference of the function to the item component, and call it there.
export class TodoList extends React.PureComponent {
render() {
return (
<ul>
{this.props.todos.map(todo => (
<Todo
key={todo.id}
{...todo}
handleClick={this.props.toggleTodo}
/>
))}
</ul>
);
}
}
and for that you don't need a statefull component.
const todo = ({id, title, handleClick} => (
<li onClick={() => handleClick(id)}>
{title}
</li>
);
export default todo
Upvotes: 2