LocalStorage参数错误(期望1实参却传0),ToDo本地存储故障求助
解决LocalStorage与Recoil状态同步的错误及实现方案
核心错误分析
- 「Expected 1 arguments, but got 0」报错:
getLocalStorage函数定义要求传入string类型的key参数,但在atom.tsx中调用getLocalStorage()时未传参,触发类型检查报错。 - 存储/读取结构不匹配:
setLocalStorage用JSON.stringify({ toDos })将数据包裹在toDos属性中,但getLocalStorage直接解析返回,导致读取结构与Recoil期望的IToDoState类型不符。 - useEffect依赖无效:监听的
[{ ...setToDos }]无法触发localStorage更新,应监听实际的toDos状态值。
分步修复代码
1. 修正LocalStorage工具函数(localStorage.tsx)
固定存储key,统一读写结构,确保类型匹配:
import { IToDoState } from "../atoms"; const STORAGE_KEY = "toDos"; export const setLocalStorage = (toDos: IToDoState) => { // 直接存储IToDoState结构,无需额外包裹 localStorage.setItem(STORAGE_KEY, JSON.stringify(toDos)); }; export const getLocalStorage = () => { // 使用固定key,无需传参 const localToDos = localStorage.getItem(STORAGE_KEY); if (localToDos) { return JSON.parse(localToDos) as IToDoState; } return undefined; };
2. 修正Recoil Atom(atom.tsx)
调用getLocalStorage时不再传参,确保初始化逻辑正确:
import { atom } from "recoil"; import { getLocalStorage } from "./util/localstorage"; export interface ITodo { id: number; text: string; } export interface IToDoState { [key: string]: ITodo[]; } export const toDoState = atom<IToDoState>({ key: "toDos", default: getLocalStorage() ?? { "To Do": [], Doing: [], Done: [], }, });
3. 修正Board组件的useEffect(Board.tsx)
修正依赖项和参数传递,确保状态变化时同步到LocalStorage:
function Board({ toDos, boardId }: IBoardProps) { const setToDos = useSetRecoilState(toDoState); const { register, setValue, handleSubmit } = useForm<IForm>(); const onValid = ({ toDo }: IForm) => { const newToDo = { id: Date.now(), text: toDo, }; setToDos((allBoards) => ({ ...allBoards, [boardId]: [...allBoards[boardId], newToDo], })); setValue("toDo", ""); }; // 监听toDos状态,变化时自动存储 useEffect(() => { setLocalStorage(toDos); }, [toDos]); // 剩余组件代码... }
进阶优化:用Recoil Atom Effects自动同步
如果想更优雅地实现状态与LocalStorage的自动同步,可以使用Atom Effects,省去手动写useEffect的步骤:
// atom.tsx import { atom } from "recoil"; export interface ITodo { id: number; text: string; } export interface IToDoState { [key: string]: ITodo[]; } const STORAGE_KEY = "toDos"; export const toDoState = atom<IToDoState>({ key: "toDos", default: { "To Do": [], Doing: [], Done: [], }, effects: [ ({ setSelf, onSet }) => { // 初始化时从LocalStorage读取数据 const savedValue = localStorage.getItem(STORAGE_KEY); if (savedValue != null) { setSelf(JSON.parse(savedValue)); } // 状态变化时自动写入LocalStorage onSet((newValue) => { localStorage.setItem(STORAGE_KEY, JSON.stringify(newValue)); }); }, ], });
使用该方案后,无需单独维护setLocalStorage和getLocalStorage函数,状态变化会自动同步到LocalStorage。
内容的提问来源于stack exchange,提问作者Seokmin JEONG
相关产品推荐
相关产品推荐

