web-dev-qa-db-ja.com

反応のuseStateフックでコールバックを使用する方法

フック付きの機能コンポーネントを使用しています。親から子の状態を更新する必要があり、親のプロップ機能を使用しています。 seStateフックが現在の状態を設定する前に実行されるので、私のprop関数が最後の状態を取得し、現在の状態ではなく、すべてが正常に機能します。 useState呼び出しの後にコールバック関数が実行されるのを待つにはどうすればよいですか。 setState(state、callback)を2番目のパラメーターとして使用しているようなものを探しています。以下は、siのコードスニペットです。

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

これを実現するには、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>
  );
};

詳細は here を参照してください。

すぐに使えるソリューションを探している場合は、 このカスタムフック をチェックしてください。これは、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>
  );
};
22
Robin Wieruch

useStateフックを使用して状態変更時にコールバック関数を呼び出す場合は、状態変更にアタッチされているuseEffectフックを使用できます。

import React, { useEffect } from 'react';

useEffect(() => {
  props.getChildChange(name); // using camelCase for variable name is recommended.
}, [name]); // this will call getChildChange when ever name changes.
5

状態が変化した場合に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);

`

4
Sunil Kumar

実際には、reactフックを使用するときはthisの使用を避けてください。それは副作用を引き起こします。そのため、react team create react hooks

thisをバインドしようとするコードを削除する場合は、setName of ParentChildに渡して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の2つのコピーを作成する必要はありません(1つはParentに、もう1つはChildに)。 「真実の単一ソース」の原則に固執し、Childは州Nameを所有する必要はありませんが、Parentから受け取ります。クリーナーノード!

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>);
} 
2
徐銘谷
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);
  collectState = collectState.bind(this);
  
  function handleChange(ele) {
    setName(ele.target.value);
  }

  function collectState() {
    return Name;
  }
  
   useEffect(() => {
    props.getChildChange(collectState());
   });

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

useEffectは、componentDidMount、componentDidUpdateとして機能するため、状態を更新すると機能します

1
Kirill