我正在尝试使用带有react-hooks的useref,但是当我调用setAccountVal方法时,尽管当我警告该值时子级的状态仍会更改为“ Ege”。您对此案有任何想法吗?
import React, { useState, useRef, useImperativeHandle, useEffect, forwardRef } from "react";
interface A {
name?: string;
}
const Child = forwardRef((props: A, ref) => {
const [acc, setAcc] = useState("Ege");
useImperativeHandle(ref, () => ({
getAlert(value: string) {
alert("getAlert from Child===>" + value);
},
setAccountVal(val: string) {
setAcc(val);
},
acc
}));
useEffect(
() => {
debugger;
setAcc(props.name || "dummy");
console.log(acc + " --");
},
[props.name]
);
const changeState = (e:React.FormEvent<HTMLInputElement>)=>{
setAcc(e.currentTarget.value);
}
return <input onChange={changeState}></input>;
})
function App() {
let [name, setName] = useState("Nate");
let nameRef = useRef<any>(null);
const submitButton = () => {
debugger;
const comp = nameRef.current;
comp.setAccountVal("Mahmut");
comp.getAlert(comp.acc);
};
return (
<div className="App">
<p>{name}</p>
<div>
<button type="button" onClick={submitButton}>
Submit
</button>
<Child ref={nameRef} />
</div>
</div>
);
}
export default App;
当我调用普通方法时,我可以看到我想要的。但是问题是我可以在acc状态上看到新的状态值,但是当我从父级获取它时,它显示的是旧的(实际上是初始状态val(“ Ege”))状态值。
编辑:实际上我想做的是
//Child component with forwardRef
const [account, setAccount] = useState("defaultAccount");
const [branch, setBranch] = useState("defaultBranch");
const [person, setPerson] = useState("defaultPerson");
useImperativeHandle(ref, () => ({
selectedAccount: account,
selectedBranch: branch,
selectedPerson: person
}));
//Parent component
const childComponentRef = useRef(null);
//Is it possible to change child component's state? Is it allowed?
childComponentRef.current.selectedAccount = "new account";
childComponentRef.current.selectedBranch = "new branch";
childComponentRef.current.selectedPerson = "new person";
alert(childComponentRef.current.selectedAccount);
alert(childComponentRef.current.selectedBranch);
alert(childComponentRef.current.selectedPerson);
//We can change these variables but child component does not rerender with new values.
好!我找到了解决方案。当我现在将ref变量与getter setter一起使用时,我也可以通过useRef设置当前值!!
//Child component with forwardRef
const [account, setAccount] = useState("defaultAccount");
const [branch, setBranch] = useState("defaultBranch");
const [person, setPerson] = useState("defaultPerson");
useImperativeHandle(ref, () => ({
**get account(){
return account;
},
set account(val : string){
setAccount(val);
},**
selectedBranch: branch,
selectedPerson: person
}));
//Parent component
const childComponentRef = useRef(null);
//Is it possible to change child component's state? Is it allowed?
childComponentRef.current.selectedAccount = "new account";
childComponentRef.current.selectedBranch = "new branch";
childComponentRef.current.selectedPerson = "new person";
alert(childComponentRef.current.selectedAccount);
alert(childComponentRef.current.selectedBranch);
alert(childComponentRef.current.selectedPerson);
//We can change these variables but child component does not rerender with new values
详细的演示:
答案 0 :(得分:2)
这是因为您在使用useImperativeHandle时未设置任何输入,因此这些函数永远不会更新。只需添加acc作为输入,它将起作用:
useImperativeHandle(ref, () => ({
getAlert(value: string) {
alert("getAlert from Child===>" + value);
},
setAccountVal(val: string) {
setAcc(val);
},
acc
}), [acc]);