reactjs - 在我的 Todo ReactApp 中,我使用的是通量。使用 useEffect 我添加了一个监听器,但是当 Todostore 更新页面时不会重新呈现。为什么不?
问题描述
下面是我的 TodoList 组件。使用 useEffect 我在组件首次安装时添加一个侦听器,并在组件安装后将其删除。但是当我添加一个做页面时不会重新渲染/更新。当我打电话给商店时,我看到商店确实使用新的 todoitem 进行了更新。我究竟做错了什么?
Todolist 组件:
import React, { useState, useEffect } from 'react';
import todoStore from '../Store/TodoStore';
import TodoItem from './TodoItem';
import * as TodoActions from '../Store/TodoActions';
function TodoList() {
const [todos, setTodos] = useState(todoStore.getAll());
const onChange = () => {
setTodos(todoStore.getAll());
};
useEffect(() => {
todoStore.on('change', onChange);
console.log('count: ', todoStore.listenerCount('change'));
return () => todoStore.removeListener('change', onChange);
}, []);
const todoComponents = todos.map((todo) => {
return <TodoItem key={todo.id} text={todo.text} complete={todo.complete} />;
});
const createTodo = () => {
TodoActions.createTodo(Date.now());
};
return (
<div>
<h1>Todo List</h1>
{todoComponents}
<button onClick={createTodo}>Create!</button>
</div>
);
}
export default TodoList;
待办事项商店:
import { EventEmitter } from 'events';
import Dispatcher from './TodoDispatcher';
class TodoStore extends EventEmitter {
constructor() {
super();
this.todos = [
{ id: 123, text: 'shopping', complete: false },
{ id: 412, text: 'laundrey', complete: false },
];
}
getAll() {
return this.todos;
}
createTodo(text) {
const id = Date.now();
this.todos.push({ id, text, complete: false });
this.emit('change');
}
handleActions(action) {
switch (action.type) {
case 'CREATE_TODO':
this.createTodo(action.text);
break;
case 'RECEIVE_TODOS':
this.todos = action.todos;
this.emit('change');
break;
default:
break;
}
}
}
const todoStore = new TodoStore();
Dispatcher.register(todoStore.handleActions.bind(todoStore));
window.todoStore = todoStore;
window.Dispatcher = Dispatcher;
export default todoStore;
创建动作:
import Dispatcher from './TodoDispatcher';
export function createTodo(text) {
Dispatcher.dispatch({
type: 'CREATE_TODO',
text,
});
}
解决方案
React doesn't rerender the page because it did not see that the store updated because the onChange had a reference to the previous state of the store.
I changed the onChange function so that a new array is created every time the store updates. something like this:
const onChange = () => {
setTodos([...todoStore.todos]);
};
推荐阅读
- orbeon - Orbeon Form - 默认情况下是否不允许下载附件?
- python-3.x - Python 3 导致 Ctrl-C 仅退出输入,而不是程序
- apache - 浏览器缓存在我的 Centos 8 上不起作用
- c++ - error while building db grid file using cmake
- c# - How do I disable RadButton from server-side?
- java - S3 GetBucketACL() 为新加坡存储桶引发异常 - 您尝试访问的存储桶必须使用指定的端点进行寻址
- puppet - 使用 fqdn_rand 并从池中删除数字
- database - Clickhouse 似乎很慢
- python - 关于我的 Python 学习路线图,我需要一些建议
- r - 从数据框创建多级 .json 文件