Как использовать обратный вызов с помощью ловушки useState в реакции - PullRequest
0 голосов
/ 02 марта 2019

Я использую функциональный компонент с крючками.Мне нужно обновить состояние в родительском от ребенка, и я использую функцию поддержки родителя для того же.Все работает отлично, за исключением того, что моя функция поддержки получает последнее состояние, а не текущее, так как моя функция поддержки выполняется до того, как 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>);
} 

Ответы [ 5 ]

0 голосов
/ 09 июля 2019

Если вы хотите иметь функцию обратного вызова для изменения состояния с помощью хука useState, вы можете сделать хук useEffect зависимым от этого состояния.

import React, { useState } from 'react';

useEffect(() => {
  props.getChildChange(Name); // using camelCase for variable name is recommended.
});
0 голосов
/ 31 мая 2019

Вы можете использовать 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, нопринимает в качестве второго параметра функцию обратного вызова:

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

Может быть установлена ​​через npm install use-state-with-callback

Примечание: Если вы хотите сделать синхронные обновления макета, используйте import { useStateWithCallbackInstant } from 'use-state-with-callback'; вместо useStateWithCallback.

0 голосов
/ 02 марта 2019

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, поэтому после обновления состояния он будет работать

0 голосов
/ 23 мая 2019

На самом деле, вы должны избегать использования this при использовании реакционных хуков.Это вызывает побочные эффекты.Вот почему реагируют команды создания react hooks.

Если вы удалите коды, которые пытаются связать this, вы можете просто передать setName из Parent в Child и вызвать его в 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).Придерживайтесь принципа «Единого источника истины», 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>);
} 
0 голосов
/ 02 марта 2019

Вы можете использовать как ниже -

this.setState(() => ({  subChartType1: value   }), () => this.props.dispatch(setChartData(null)));
...