我是用React Libray构建Web的新手,并使用next.js和typscript来创建Web应用程序。我在试着做一个待办事项列表的网络应用。
我创建了一个接口,用于收集列表数据,如下所示:
interface listData {
text: string,
isDone: boolean,
viewMode?: { display: '' },
editMode?: { display: 'none' },
}
const [list, setList] = useState<listData[]>([]);
const addList = (item: any) => {
if (item !== "") {
const newList = [...list, { text: item, isDone: false, viewMode: { display: '' }, editMode: { display: 'none' } }];
localStorage.setItem('listData', JSON.stringify([...list, { text: item, isDone: false, viewMode: { display: '' }, editMode: { display: 'none' } }]));
setList(newList);
};
}
我在setList(newList)时得到了下面的vscode错误:
Argument of type '(listData | { text: string; isDone: boolean; viewMode: { display: string; }; editMode: { display: string; }; })[]' is not assignable to parameter of type 'SetStateAction<listData[]>'.
Type '(listData | { text: string; isDone: boolean; viewMode: { display: string; }; editMode: { display: string; }; })[]' is not assignable to type 'listData[]'.
Type 'listData | { text: string; isDone: boolean; viewMode: { display: string; }; editMode: { display: string; }; }' is not assignable to type 'listData'.
Type '{ text: string; isDone: boolean; viewMode: { display: string; }; editMode: { display: string; }; }' is not assignable to type 'listData'.
The types of 'viewMode.display' are incompatible between these types.
Type 'string' is not assignable to type '""'.ts(2345)
viewMode和editMode是为display css构建的,用于显示将显示哪个标签,比如当用户按下编辑按钮时,然后是viewmode.display:'none',否则为editMode。display:没有
现在我有一个关于addList赋值的问题,请看下图。我不知道现在addList函数中的问题是什么,当我setList(newList)。希望有人能告诉我我在哪里工作,真的很感谢。
return (
<>
<div className={styles.bodyOuterDiv} >
...
<ul >
{list.map((item, index) => {
return (
<li key={index} className={styles.todoListOuterLi} >
<div className={item.isDone ? styles.todoListItemsWithIsDone : styles.todoListItems} style={item.viewMode}>
{item.text}
</div>
<textarea className={styles.todoListTextArea} value={item.text} onChange={(e) => { setItem(e.target.value) }} style={item.editMode} />
...
</li>
);
})}
</ul>
...
</div>
</>
);
2条答案
按热度按时间lvjbypge1#
问题是,因为你没有
newList
或其中的新对象的类型注解,TypeScript * 从属性值的类型推断 * 这些属性的类型。当它这样做时,TypeScript将""
和"none"
推断为string
类型(而不是字符串文字类型""
和"none"
),但您的接口需要字符串文字类型""
和"none"
。有几种方法可以解决这个问题。可能最直接的方法是告诉TypeScript
newList
是一个listData[]
(但请继续阅读,还有一些其他问题):Playground链接
旁注:
item
参数的类型应该是string
,而不是any
:通过将其设置为
any
,您可以执行addList(42)
,这将在列表中放置一个具有text: 42
的对象,这不是类型所说的那样。也就是说,还有几件事:
1.每当基于现有状态设置状态时,最好使用状态设置器的回调形式,而不是依赖于
addList
关闭的list
副本,因为那可能是过时的。1.没有理由重复添加新项的代码,只需在本地存储中存储时使用
newList
即可。所以:
Playground链接
使用回调表单还可以记忆
addList
,如果要将其传递到的组件是记忆的,这可能很有用。每次都给该组件一个新的addList
强制它重新渲染,而如果addList
是稳定的(因为它是记忆化的),该组件可能能够避免重新渲染。但是是否要存储addList
取决于要将其提供给的组件。(更多关于这一点,请参见我对useCallback
here的回答。2ul0zpep2#
修复了第一个类型错误: