我正在使用带有钩子的功能组件。我需要更新状态在父母从一个孩子。我使用的道具功能在父母。 一切都很好,除了我的道具函数是得到以前的状态,而不是当前的状态。我的道具函数在useState钩子设置当前状态之前执行。 我怎么能在useState调用后等待回调函数执行。我正在寻找类似setState(状态,回调)从基于类的组件。

下面是代码片段:

function Parent() {
  const [Name, setName] = useState("");
  getChildChange = getChildChange.bind(this);
  function getChildChange(value) {
    setName(value);
  }

  return <div> {Name} :
    <Child getChildChange={getChildChange} ></Child>
  </div>
}

function Child(props) {
  const [Name, setName] = useState("");
  handleChange = handleChange.bind(this);

  function handleChange(ele) {
    setName(ele.target.value);
    props.getChildChange(collectState());
  }

  function collectState() {
    return Name;
  }

  return (<div>
    <input onChange={handleChange} value={Name}></input>
  </div>);
} 

当前回答

实际上,你应该避免在使用react钩子时使用这个。它会产生副作用。这就是react团队创建react钩子的原因。

如果你删除了试图绑定它的代码,你可以简单地将父的setName传递给子,并在handleChange中调用它。清洁代码!

function Parent() {
  const [Name, setName] = useState("");

  return <div> {Name} :
    <Child setName={setName} ></Child>
  </div>
}

function Child(props) {
  const [Name, setName] = useState("");

  function handleChange(ele) {
    setName(ele.target.value);
    props.setName(ele.target.value);
  }

  return (<div>
    <input onChange={handleChange} value={Name}></input>
  </div>);
} 

此外,您不必创建Name的两个副本(一个在Parent中,另一个在Child中)。坚持“单一真相来源”原则,孩子不必拥有国家名称,而是从父母那里接受。清洁节点!

function Parent() {
  const [Name, setName] = useState("");

  return <div> {Name} :
    <Child setName={setName} Name={Name}></Child>
  </div>
}

function Child(props) {    
  function handleChange(ele) {
    props.setName(ele.target.value);
  }

  return (<div>
    <input onChange={handleChange} value={props.Name}></input>
  </div>);
} 

其他回答

你可以利用useCallback钩子来做到这一点。

function Parent() {
  const [name, setName] = useState("");
  const getChildChange = useCallback( (updatedName) => {
    setName(updatedName);
  }, []);

  return <div> {name} :
    <Child getChildChange={getChildChange} ></Child>
  </div>
}

function Child(props) {
  const [name, setName] = useState("");

  function handleChange(ele) {
    setName(ele.target.value);
    props.getChildChange(ele.target.value);
  }

  function collectState() {
    return name;
  }

  return (<div>
    <input onChange={handleChange} value={name}></input>
  </div>);
}

我们可以编写自定义函数,它将在状态发生任何变化时调用callBack函数

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const useStateCallbackWrapper = (initilValue, callBack) => {
  const [state, setState] = useState(initilValue);
  useEffect(() => callBack(state), [state]);
  return [state, setState];
};

const callBack = state => {
  console.log("---------------", state);
};
function App() {
  const [count, setCount] = useStateCallbackWrapper(0, callBack);
  return (
    <div className="App">
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>+</button>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

`

React16。如果你想使用useState钩子在状态改变时调用一个回调函数,你可以使用useEffect钩子附加到状态改变。

import React, { useEffect } from "react";

useEffect(() => {
  props.getChildChange(name); // using camelCase for functions is recommended.
}, [name]); // this will call getChildChange on initial render and when ever name changes.

另一种实现方法:

const [Name, setName] = useState({val:"", callback: null}); React.useEffect (() = > { console.log(名字) const {callback} =名称; Callback && Callback (); },[名字]); setName ({val:“foo”,回调:()= > setName ({val:“然后酒吧”})})

实际上,你应该避免在使用react钩子时使用这个。它会产生副作用。这就是react团队创建react钩子的原因。

如果你删除了试图绑定它的代码,你可以简单地将父的setName传递给子,并在handleChange中调用它。清洁代码!

function Parent() {
  const [Name, setName] = useState("");

  return <div> {Name} :
    <Child setName={setName} ></Child>
  </div>
}

function Child(props) {
  const [Name, setName] = useState("");

  function handleChange(ele) {
    setName(ele.target.value);
    props.setName(ele.target.value);
  }

  return (<div>
    <input onChange={handleChange} value={Name}></input>
  </div>);
} 

此外,您不必创建Name的两个副本(一个在Parent中,另一个在Child中)。坚持“单一真相来源”原则,孩子不必拥有国家名称,而是从父母那里接受。清洁节点!

function Parent() {
  const [Name, setName] = useState("");

  return <div> {Name} :
    <Child setName={setName} Name={Name}></Child>
  </div>
}

function Child(props) {    
  function handleChange(ele) {
    props.setName(ele.target.value);
  }

  return (<div>
    <input onChange={handleChange} value={props.Name}></input>
  </div>);
}