1. ホーム
  2. reactjs

[解決済み] reactのuseStateフックでコールバックを使う方法 [重複]。

2022-03-05 09:52:21

質問

私はフックを持つ機能的なコンポーネントを使用しています。私は子から親の状態を更新する必要があります。私は親でprop関数を使用しています。 私のプロップ関数が現在の状態ではなく、前の状態を取得していることを除いて、すべてがうまく動作します。私のプロップ関数は、以下の前に実行されます。 使用状態 フックが現在の状態を設定する。 useState呼び出しの後、コールバック関数が実行されるのを待つにはどうすればよいのでしょうか。私は次のようなものを探している。 setState(state,callback) クラスベースのコンポーネントから。

以下は、そのコード・スニペットです。

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>);
} 

解決方法は?

useEffect/useLayoutEffectを使用すると実現できます。

const SomeComponent = () => {
  const [count, setCount] = React.useState(0)

  React.useEffect(() => {
    if (count > 1) {
      document.title = 'Threshold of over 1 reached.';
    } else {
      document.title = 'No threshold reached.';
    }
  }, [count]);

  return (
    <div>
      <p>{count}</p>

      <button type="button" onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
};

詳しくはこちら こちら .

もし、すぐに使えるソリューションをお探しなら、以下をご覧ください。 このカスタムフック は、useStateと同様に動作しますが、2番目のパラメータとしてコールバック関数を受け取ります。

// npm install use-state-with-callback

import useStateWithCallback from 'use-state-with-callback';

const SomeOtherComponent = () => {
  const [count, setCount] = useStateWithCallback(0, count => {
    if (count > 1) {
      document.title = 'Threshold of over 1 reached.';
    } else {
      document.title = 'No threshold reached.';
    }
  });

  return (
    <div>
      <p>{count}</p>

      <button type="button" onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
};