Typescript react不调用useState
背景: 我使用React钩子创建了一个运行良好的CRUD应用程序。 从教程中的代码开始,我想将状态组件从每个视图中分解出来,放到一个类中。我这样做的原因是创建一个可重用的、静态类型的viewmodel对象 问题: 在AddUserForm.tsx中,我正在处理函数Typescript react不调用useState,typescript,react-hooks,Typescript,React Hooks,背景: 我使用React钩子创建了一个运行良好的CRUD应用程序。 从教程中的代码开始,我想将状态组件从每个视图中分解出来,放到一个类中。我这样做的原因是创建一个可重用的、静态类型的viewmodel对象 问题: 在AddUserForm.tsx中,我正在处理函数handleInputChange中的输入更改。我正在使用VS code debugger单步执行代码,我得到了一个奇怪的行为:我在调用setCurrentUser的行上放置了一个断点,但是当我开始调试时,断点移到了后面的行,这是结束的
handleInputChange
中的输入更改。我正在使用VS code debugger单步执行代码,我得到了一个奇怪的行为:我在调用setCurrentUser
的行上放置了一个断点,但是当我开始调试时,断点移到了后面的行,这是结束的大括号(所有代码文件都保存到磁盘上,应用程序构建在TS中)。由于某种原因,setCurrentUser
从未执行
AddUserForm.tsx
const AddUserForm = (props :any) => {
const vm: UserViewModel = props.vm as UserViewModel;
const handleInputChange = (event:any) => {
const vm2 = vm; // closure
const { name, value } = event.target;
vm2.setCurrentUser({...vm2.currentUser, [name]:value}); // problem here. the call to setCurrentUser does not execute.
}
return (
<form onSubmit={event => {
event.preventDefault();
if(! vm.currentUser.name || ! vm.currentUser.username)
return;
vm.addUser(vm.currentUser);
vm.setCurrentUser(new user());
}}>
<label>Name</label>
<input type="text" name="name" value={vm.currentUser.name} onChange={handleInputChange}></input>
<label>Username</label>
<input type="text" name="username" value={vm.currentUser.username} onChange={handleInputChange}></input>
<button>Add new user</button>
</form>
)
}
export default AddUserForm;
const AddUserForm=(props:any)=>{
const vm:UserViewModel=props.vm作为UserViewModel;
常量handleInputChange=(事件:任意)=>{
const vm2=vm;//闭包
常量{name,value}=event.target;
vm2.setCurrentUser({…vm2.currentUser,[名称]:值});//此处存在问题。对setCurrentUser的调用未执行。
}
返回(
{
event.preventDefault();
如果(!vm.currentUser.name | |!vm.currentUser.username)
返回;
vm.addUser(vm.currentUser);
setCurrentUser(新用户());
}}>
名称
用户名
添加新用户
)
}
导出默认AddUserForm;
UserViewModel.tsx
export default class UserViewModel
{
public currentUser: user;
public users: user[];
public editing : boolean;
public setUsers : any;
public setCurrentUser : any;
public setEditing : any;
constructor() {
const usersData: user[] = [
{id:1, name:'Tania', username:'floppydiskette'},
{id:2, name:'Craig', username:'siliconedolon'},
{id:3, name:'Ben', username:'benisphere'}
];
this.editing = false;
this.users = usersData;
this.currentUser = new user();
this.setCurrentUser = useState<user>(this.currentUser)[1];
this.setUsers = useState<user[]>(this.users)[1];
this.setEditing = useState<boolean>(this.editing)[1];
}
public addUser: (usr:user) => void = (usr :user) => {
usr.id = this.users.length + 1;
this.setUsers([...this.users, usr]);
};
public editUser: (user:user) => void = (user:user) => {
this.setEditing(true);
this.setCurrentUser(user)
};
public updateUser: (updatedUser:user) => void = (updatedUser:user) => {
this.setEditing(false);
this.setUsers(this.users.map((user) => (user.id === updatedUser.id ? updatedUser : user)));
};
public deleteUser: (id:number) => void = (id:number) => {
this.setEditing(false);
this.setUsers(this.users.filter((user) => user.id !== id));
};
}
导出默认类UserViewModel
{
公共用户:用户;
公共用户:用户[];
公共编辑:布尔;
公共用户:任何;
公共设置当前用户:任何;
公共编辑:任何;
构造函数(){
const usersData:user[]=[
{id:1,名称:'Tania',用户名:'floppydiskette'},
{id:2,名称:'Craig',用户名:'siliconedolon'},
{id:3,名称:'Ben',用户名:'benisphere'}
];
this.editing=false;
this.users=usersData;
this.currentUser=新用户();
this.setCurrentUser=useState(this.currentUser)[1];
this.setUsers=useState(this.users)[1];
this.setEditing=useState(this.editing)[1];
}
public addUser:(usr:user)=>void=(usr:user)=>{
usr.id=this.users.length+1;
this.setUsers([…this.users,usr]);
};
public editUser:(用户:用户)=>void=(用户:用户)=>{
此.setEditing(true);
this.setCurrentUser(用户)
};
public updateUser:(updateUser:user)=>void=(updateUser:user)=>{
此参数为.setEditing(false);
this.setUsers(this.users.map((user)=>(user.id==updateuser.id?updateuser:user));
};
public deleteUser:(id:number)=>void=(id:number)=>{
此参数为.setEditing(false);
this.setUsers(this.users.filter((user)=>user.id!==id));
};
}
useState是一个钩子,只在函数组件中工作,不在类组件中工作 请参阅
另外,您的“viewModel”应该只包含数据和代码。就React而言,它没有任何“状态”。只有React组件具有这种意义上的状态。
const vm2=vm;//结束语
no:)您当前的方法行不通。问题是useState
hook保持自己的状态。所以this.setUsers
不会改变原始对象,而是用新对象替换整个对象,所以this.users
将不会被修改,并且基本上会丢失所有更改。如果您想创建带有钩子的可重用代码段,请选中“自定义钩子”,而不是尝试构建MVVM弗兰肯斯坦怪物。挂钩是在FP范式中设计的,它们不会很好地处理OOP模式。@YuryTarabanko,谢谢。继续到vue。