undefined
undefined

Reputation: 6884

React PureComponent pass paramater from Child component

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

Answers (1)

k.s.
k.s.

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

Related Questions