Typescript react不调用useState

Typescript react不调用useState,typescript,react-hooks,Typescript,React Hooks,背景: 我使用React钩子创建了一个运行良好的CRUD应用程序。 从教程中的代码开始,我想将状态组件从每个视图中分解出来,放到一个类中。我这样做的原因是创建一个可重用的、静态类型的viewmodel对象 问题: 在AddUserForm.tsx中,我正在处理函数handleInputChange中的输入更改。我正在使用VS code debugger单步执行代码,我得到了一个奇怪的行为:我在调用setCurrentUser的行上放置了一个断点,但是当我开始调试时,断点移到了后面的行,这是结束的

背景:

我使用React钩子创建了一个运行良好的CRUD应用程序。 从教程中的代码开始,我想将状态组件从每个视图中分解出来,放到一个类中。我这样做的原因是创建一个可重用的、静态类型的viewmodel对象

问题:

在AddUserForm.tsx中,我正在处理函数
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。