我正在尝试开发一个带有每日条纹的to-do list应用,所以每当你在一天中检查所有的to-do,你的条纹就会增加。我正在使用带有Typescript的Solid。我正在制作一个Streak组件,它通过props从App接收商店信号state
和setState
,定义如下(Todo
是一个只有字符串 text 和布尔 complete 的类型:
const [state, setState] = createStore<{days: number; todos: Todo[]}> ({
days: 0,
todos: todos(),
})
我还在App中做了一个效果,查看选中的todos是否与完整的todos列表长度相同,因此days
变量可以递增:
createEffect(() => {
let newTodos = todos();
let getOneMoreDay: number = 0;
if (newTodos.filter((x) => x.complete === true).length === newTodos.length)
getOneMoreDay = 1;
setState({
days: state.days + getOneMoreDay,
todos: newTodos,
});
});
问题是,在页面中,当我检查所有待办事项时,Streak组件开始循环,而不是显示1 day
,它显示8492 days
,并在控制台中显示以下消息:* 未捕获的内部错误:太多的递归 *。那么,我做错了什么?我应该用其他函数代替createEffect吗?我试过createMemo,但发生的事情是,天甚至没有更新。问我任何细节,可以帮助你,我很抱歉的长问题。我是非常新的网络开发。
1条答案
按热度按时间svmlkihl1#
因为您正在设置状态,这会导致无限循环。效果是用于处理副作用的,所以不应使用它们来更新状态。如果无论如何都要更新状态,请确保运行不会触发无限循环的部分状态更新,或者使用
on
方法在更新其他属性时侦听某些属性。从您的代码中,我可以看到您正在存储信号:
商店本身是React式的,可以存储多个物品而不需要额外的信号。这就是拥有商店的全部意义。
要回答你的问题,有多种方法。如果你要使用一个效果,检查是否所有待办事项都标记为完成,并只更新
days
值:您可以在以下位置找到现场演示:https://playground.solidjs.com/anonymous/bea60daa-cf72-4880-82e4-ccdac72fbd8b
另一种更好的方法是在标记最后一个
todo
项done
时更新days
:下面是一个现场演示:https://playground.solidjs.com/anonymous/927300e2-d801-4e48-b461-4e29527f5788
通过侦听未由内部回调更新的属性,可以使效果不受无限循环的影响:
另一种方法是记忆
todos
,这样其他属性就不会触发该效果: