В React-хуках UseRef я не могу получить новое значение состояния - PullRequest
0 голосов
/ 13 февраля 2019

Я пытаюсь использовать 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, я могу также установить текущие значения с помощью 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 голосов
/ 13 февраля 2019

Это потому, что вы используете useImperativeHandle без установки каких-либо входов, поэтому функции никогда не обновляются.Просто добавьте acc в качестве ввода, и оно будет работать:

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

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

  },
  acc
}), [acc]);
...