当任何状态发生变化时,在React组件的渲染函数中调用返回JSX的方法会导致性能损失吗?

时间:2017-12-02 01:14:29

标签: javascript performance reactjs

每当我在输入中输入内容时,state.addTodo都会更新,从而导致调用render,即使它没有使用allTodos,也会调用state.addTodo。这是否会给性能带来影响?如果是,我该如何解决? (调用render中的函数会降低性能,还是因为它只更新V-DOM而不是DOM?)

此外,是否有任何简单的方法可以重置表单以及将所有变量(此处仅state.addTodo)重置为与该表单关联的默认值?

class App extends Component {
  state = {
    todos: {},
    addTodo: ""
  };

  allTodos = () => {
    if(Object.keys(this.state.todos).length === 0)
      return null;
    const jsx = Object.keys(this.state.todos).map(timestamp => (
      <li key={timestamp}>{this.state.todos[timestamp].todo}</li>
    ));
    return jsx;
  };

  onSubmitHandler = e => {
    e.preventDefault();
    const timestamp = Date.now()*10000 + Math.random()*10000;
    this.setState(prevState => ({
      todos: {...prevState.todos, 
        [timestamp]: {
          todo: prevState.addTodo,
          done: false
        }
      },
      addTodo: ""
    }));
    e.target.reset();
  };

  onChangeHandler = e => {
    const name= e.target.name, value = e.target.value;
    this.setState(prevState => ({
      [name]: value
    }));
  }

  render() {
    return (
      <div>
        <h3>All todos</h3>
        <ul>{this.allTodos()}</ul>

        <form onSubmit={this.onSubmitHandler}>
          <input type="text" name="addTodo" onChange={this.onChangeHandler}/>
          <button type="submit">Add</button>
        </form>
      </div>
    );
  }
}

1 个答案:

答案 0 :(得分:1)

即使您没有对state.todos进行更改,您也注意到所有待办事项都被重新渲染是正确的。如果您不想重新渲染这些待办事项,您可以制作一个全新的组件,只需渲染这些待办事项。 EX:

const TodoList = ({ todos }) => {
  if(Object.keys(todos).length === 0)
      return null;
  const todoList = Object.keys(todos).map(timestamp => (
    <li key={timestamp}>{todos[timestamp].todo}</li>
  ));
  return todoList;
}

class App extends Component {
  state = {
    todos: {},
    addTodo: ""
  };

  ...other handlers are the same

  render() {
    return (
      <div>
        <h3>All todos</h3>
        <ul><TodoList todos={this.state.todos} /></ul>

        <form onSubmit={this.onSubmitHandler}>
          <input type="text" name="addTodo" onChange={this.onChangeHandler}/>
          <button type="submit">Add</button>
        </form>
      </div>
    );
  }
}

这是React非常常见的情况,正是React被认为是'组合'的原因。既然todos在一个新组件中,React可以告诉组件的props(todos)没有改变,它们也不会被重新渲染。

就你的第二个问题而言,如果你想重置多个变量,你总是可以使用这些变量的默认值来调用setState。

EX:

this.setState({
    todos: {},
    addTodo: "",
})