在React-Hooks UseRef中,我无法获取新的状态值

时间:2019-02-13 08:20:43

标签: reactjs typescript ecmascript-6 react-hooks react-ref

我正在尝试使用带有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

详细的演示:

Edit React-Ref with Hooks

1 个答案:

答案 0 :(得分:2)

这是因为您在使用useImperativeHandle时未设置任何输入,因此这些函数永远不会更新。只需添加acc作为输入,它将起作用:

useImperativeHandle(ref, () => ({
  getAlert(value: string) {
    alert("getAlert from Child===>" + value);
  },

  setAccountVal(val: string) {
    setAcc(val);

  },
  acc
}), [acc]);