避免 `setTimeout` 'hack' 以确保状态同步
Avoiding `setTimeout` 'hack' to ensure state is in sync
我使用 React 编写了一个小型待办事项应用程序,用户可以在其中添加和删除列表中的项目。
作为奖励功能,该列表会在用户修改后保存到 localStorage
,并在组件的初始安装时使用。
在addTodo
和removeTodo
方法中,模式都是这样的:
- 通过添加或删除
this.state.todos
的项目来设置新状态
- 复制状态到
localStorage
例如,这里是 removeTodo
方法:
removeTodo(indexOfItemToRemove) {
const todosCopy = this.state.todos.slice();
todosCopy.splice(indexOfItemToRemove, 1);
this.setState({
todos: todosCopy
});
this.updateLocalStorageWithState();
}
这是我目前正在做的将 this.state.todos
保存到 localStorage
updateLocalStorageWithState() {
setTimeout(() => {
localStorage.setItem('localStorageTodos', JSON.stringify(this.state.todos));
}, 1);
}
我发现在不使用 setTimeout
的情况下,localStorage
总是落后 1 步,使用的是用户可能认为是过时版本的列表。
这感觉像是黑客攻击。如何在不使用 setTimeout
hack 的情况下合并做同样事情的方法?
setState()
不一定同步执行。这会导致您遇到的行为:
setState()
does not immediately mutate this.state
but creates a pending state transition. Accessing this.state
after calling this method can potentially return the existing value.
There is no guarantee of synchronous operation of calls to setState
and calls may be batched for performance gains.
幸运的是,setState()
接受第二个参数,这是状态更新完成时调用的回调。您可以使用它来同步您的本地存储条目:
this.setState({
todos: todosCopy
}, () => {
localStorage.setItem('localStorageTodos', JSON.stringify(this.state.todos));
});
或者,为什么不直接设置本地存储条目而不是先从 state
读取?
this.setState({
todos: todosCopy
});
localStorage.setItem('localStorageTodos', JSON.stringify(todosCopy));
我使用 React 编写了一个小型待办事项应用程序,用户可以在其中添加和删除列表中的项目。
作为奖励功能,该列表会在用户修改后保存到 localStorage
,并在组件的初始安装时使用。
在addTodo
和removeTodo
方法中,模式都是这样的:
- 通过添加或删除
this.state.todos
的项目来设置新状态
- 复制状态到
localStorage
例如,这里是 removeTodo
方法:
removeTodo(indexOfItemToRemove) {
const todosCopy = this.state.todos.slice();
todosCopy.splice(indexOfItemToRemove, 1);
this.setState({
todos: todosCopy
});
this.updateLocalStorageWithState();
}
这是我目前正在做的将 this.state.todos
保存到 localStorage
updateLocalStorageWithState() {
setTimeout(() => {
localStorage.setItem('localStorageTodos', JSON.stringify(this.state.todos));
}, 1);
}
我发现在不使用 setTimeout
的情况下,localStorage
总是落后 1 步,使用的是用户可能认为是过时版本的列表。
这感觉像是黑客攻击。如何在不使用 setTimeout
hack 的情况下合并做同样事情的方法?
setState()
不一定同步执行。这会导致您遇到的行为:
setState()
does not immediately mutatethis.state
but creates a pending state transition. Accessingthis.state
after calling this method can potentially return the existing value.There is no guarantee of synchronous operation of calls to
setState
and calls may be batched for performance gains.
幸运的是,setState()
接受第二个参数,这是状态更新完成时调用的回调。您可以使用它来同步您的本地存储条目:
this.setState({
todos: todosCopy
}, () => {
localStorage.setItem('localStorageTodos', JSON.stringify(this.state.todos));
});
或者,为什么不直接设置本地存储条目而不是先从 state
读取?
this.setState({
todos: todosCopy
});
localStorage.setItem('localStorageTodos', JSON.stringify(todosCopy));