web-dev-qa-db-fra.com

Comment utiliser le rappel avec le crochet useState dans React

J'utilise un composant fonctionnel avec des crochets. J'ai besoin de mettre à jour l'état dans le parent de l'enfant et j'utilise la fonction prop du parent pour cela. Tout fonctionne bien sauf que ma fonction prop obtient le dernier état et non le courant car ma fonction prop est exécutée avant seState hook définissant l'état actuel. Comment puis-je attendre que ma fonction de rappel soit exécutée après l'appel useState. Je cherche quelque chose comme si nous utilisons setState (état, rappel) comme deuxième paramètre. ci-dessous si l'extrait de code pour le même.

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

Vous pouvez utiliser useEffect/useLayoutEffect pour y parvenir:

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

En savoir plus sur ici .

Si vous recherchez une solution prête à l'emploi, consultez ce crochet personnalisé qui fonctionne comme useState mais accepte comme deuxième paramètre une fonction de rappel:

// 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

Si vous souhaitez appeler une fonction de rappel lors d'un changement d'état à l'aide du crochet useState, vous pouvez utiliser le crochet useEffect attaché au changement d'état.

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
Abhijith Sasikumar

nous pouvons écrire une fonction de personnalisation qui appellera la fonction callBack si des changements d'état

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

En fait, vous devez éviter d'utiliser this lorsque vous utilisez des hooks react. Cela provoque des effets secondaires. Voilà pourquoi l'équipe de réaction crée react hooks.

Si vous supprimez des codes qui essaient de lier this, vous pouvez simplement passer setName de Parent à Child et l'appeler dans handleChange . Code plus propre!

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

De plus, vous n'avez pas besoin de créer deux copies de Name (une dans Parent et l'autre dans Child). Restez fidèle au principe de la "source unique de vérité", Child n'a pas à posséder l'état Name mais à le recevoir de Parent. Noeud plus propre!

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 agit comme componentDidMount, componentDidUpdate, donc après la mise à jour de l'état, cela fonctionnera

1
Kirill