我有the following app,它允许我单击列表中的待办事项,一次只能选择一个待办事项:

class State {
  @observable todos = [
    { id: '1', description: 'Do this' },
    { id: '2', description: 'Do that' },
    { id: '3', description: 'Do this third thing' }
  ]
}

const state = new State();

const TodoView = observer(({ todo, isSelected, onClick }) => (
  <div onClick={onClick}>
    { todo.description } { isSelected && ' (selected)' }
  </div>
));

@observer
class App extends Component {
  @observable selected = null;
  render () {
    return <div>
      { state.todos.map((todo) =>
       <TodoView
         key={todo.id}
         todo={todo}
         isSelected={this.selected === todo}
         onClick={() => this.selected = todo} />
       )}
    </div>;
  }
}

当我选择一个新的待办事项时,将重新渲染待办事项的整个列表。有什么方法可以只重新渲染选定的待办事项和未选定的待办事项,而不会用其他数据弄乱状态?

最佳答案

您可以使用可观察的selected并为每个App赋予一个自己的密钥来观察,而不是在每个TodoView所依赖的map组件中都没有可观察到的TodoView。将此map作为 Prop 传递给TodoView,并检查map是否以待办事项ID为键。 This way only the selected and deselected todos will be re-rendered:

class State {
  @observable todos = [
    { id: '1', description: 'Do this' },
    { id: '2', description: 'Do that' },
    { id: '3', description: 'Do this third thing' }
  ]
}

const state = new State();

const TodoView = observer(({ todo, selectedMap, onClick }) => (
  <div onClick={onClick}>
    { todo.description } { selectedMap.has(todo.id) && ' (selected)' }
  </div>
));

@observer
class App extends Component {
  selectedMap = observable.map({});

  onClick = (todo) => {
    this.selectedMap.clear();
    this.selectedMap.set(todo.id, todo);
  };

  render () {
    return <div>
      { state.todos.map((todo, idx) =>
       <TodoView
         key={todo.id}
         todo={todo}
         selectedMap={this.selectedMap}
         onClick={() => this.onClick(todo)} />
       )}
    </div>;
  }
}

09-20 21:43