[英]React Typescript - Argument of type is not assignable to parameter of type 'SetStateAction<User | Record<string, never>>'
I have a simple React web app with data (List of object) of Users, Todos And Posts, where I show, update and delete the data.我有一个简单的 React web 应用程序,其中包含用户、待办事项和帖子的数据(对象列表),我在其中显示、更新和删除数据。
I have a Component named UserView where I get the user data from the props, and then I save the data in the state with useEffect我有一个名为 UserView 的组件,我从道具中获取用户数据,然后使用 useEffect 将数据保存在 state 中
interface UserViewProps {
userData: User;
}
export default function UserView({
userData,
...
}: UserViewProps) {
const [user, setUser] = useState<User | Record<string, never>>({});
useEffect(() => {
...
setUser({ ...userData });
}, [todosData]);
The problem is when I want to change the user state from input to pass to a callback function with destructuring:问题是当我想通过解构将用户 state 从输入更改为传递给回调 function 时:
<input
onChange={(e) =>
setUser({
...user,
name: e.target.value,
})
}
I receive the following TypeScript error:我收到以下 TypeScript 错误:
Argument of type '{ name: string; id: number; username: string; email: string; address: Address; phone: string; website: string; company: Company; } | { name: string; }' is not assignable to parameter of type 'SetStateAction<User | Record<string, never>>'.
Type '{ name: string; }' is not assignable to type 'SetStateAction<User | Record<string, never>>'.
Type '{ name: string; }' is not assignable to type 'Record<string, never>'.
Property 'name' is incompatible with index signature.
Type 'string' is not assignable to type 'never'.ts(2345)
When I change当我改变
const [user, setUser] = useState<User | Record<string, never>>({});
to到
const [user, setUser] = useState<User | any>({});
Everything works How can I fix this TypeScript error?一切正常 我该如何解决这个 TypeScript 错误?
Full code below:完整代码如下:
import React, { useEffect, useState } from 'react';
import { Post, Todo, User } from '../../../helpers/utils';
import { StyledUserView } from './style';
interface UserViewProps {
userData: User;
todosData: Todo[];
postsData: Post[];
handleUserDelete: (userId: number) => void;
handleUserUpdate: (updatedUser: User) => void;
}
export default function UserView({
userData,
todosData,
postsData,
handleUserDelete,
handleUserUpdate,
}: UserViewProps) {
const [isUncompletedTodo, setIsUncompletedTodo] = useState(false);
const [isShowOtherData, setIsShowOtherData] = useState(false);
const [user, setUser] = useState<User | any>({});
useEffect(() => {
if (todosData.find((todo) => todo.completed === false)) {
setIsUncompletedTodo(true);
} else {
setIsUncompletedTodo(false);
}
setUser({ ...userData });
}, [todosData]);
return (
<StyledUserView isUncompletedTodo={isUncompletedTodo}>
ID: {user.id} <br />
<label htmlFor={`${user.id}-name-input`}>Name:</label>{' '}
<input
onChange={(e) =>
setUser({
...user,
name: e.target.value,
})
}
id={`${user.id}-name-input`}
type="text"
value={user.name}
/>{' '}
<br />
<label htmlFor={`${user.id}-email-input`}>Email:</label>{' '}
<input
onChange={(e) =>
setUser({
...user,
email: e.target.value,
})
}
id={`${user.id}-email-input`}
type="text"
value={user.email}
/>{' '}
<br />
{isShowOtherData && (
<section className="other-data">
<label htmlFor={`${user.id}-street-input`}>Street:</label>{' '}
<input
onChange={(e) =>
setUser({
...user,
address: {
...user.address,
street: e.target.value,
},
})
}
id={`${user.id}-street-input`}
type="text"
value={user.address.street}
/>{' '}
<br />
<label htmlFor={`${user.id}-city-input`}>City:</label>{' '}
<input
id={`${user.id}-city-input`}
type="text"
value={user.address.city}
onChange={(e) =>
setUser({
...user,
address: {
...user.address,
city: e.target.value,
},
})
}
/>{' '}
<br />
<label htmlFor={`${user.id}-zip-code-input`}>Zip Code:</label>{' '}
<input
id={`${user.id}-zip-code-input`}
type="text"
value={user.address.zipcode}
onChange={(e) =>
setUser({
...user,
address: {
...user.address,
zipcode: e.target.value,
},
})
}
/>{' '}
<br />
</section>
)}
<button
onClick={() => {
setIsShowOtherData(!isShowOtherData);
}}
>
{isShowOtherData ? 'Hide Other Data' : 'Show Other Data'}
</button>
<button onClick={() => handleUserUpdate(user)}>Update</button>
<button
onClick={() => {
handleUserDelete(user.id);
}}
>
Delete
</button>
</StyledUserView>
);
}
You can try to change你可以尝试改变
const [user, setUser] = useState<User | Record<string, never>>({});
// to
const [user, setUser] = useState<User | Record<string, any>>({});
//or
const [user, setUser] = useState<User | Record<string, string>>({});
Add inital user name as empty string将初始用户名添加为空字符串
const [user, setUser] = useState<{ name: string }>({
name: ""
});
if the name is a variable then you need to do [name] else it is static then "name"如果名称是一个变量,那么你需要做 [名称] 否则它是 static 然后是“名称”
<input
onChange={(e) =>
setUser(prv=>{
...prv,
[name]: e.target.value,
})
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.