Где я должен объявить функции, которые вызываются в хуке useEffect ()? - PullRequest
0 голосов
/ 02 июля 2019

Итак, у меня следующая ситуация при использовании useEffect, который вызывает функции, зависящие от состояния.

Пример:

// INSIDE APP COMPONENT

const [someState, setSomeState] = React.useState(0);
const [someTrigger, setSomeTrigger] = React.useState(false);

function someFunction() {
  return someState + 1;  
}

React.useEffect(() => {

  const newState = someFunction();  // 'someFunction' IS BEING CALLED HERE
  setSomeState(newState);

},[someTrigger])

Вопросы:

В этом случае я должен объявить someFunction внутри useEffect() или безопасно хранить его снаружи (но внутри тела компонента)?

Я мог бы добавить его в массив dependency, но это повредит возможности восстановления моего кода, поскольку я хочу сосредоточиться на trigger.

Поскольку useEffect() будет запускаться после нового рендеринга, безопасно ли предполагать, что в нем будут свежие копии функций, которые я вызываю?

Существует ли основное правило, когда вы должны объявлять функции внутри хука useEffect или когда обязательно добавлять его в массив зависимостей?

РЕДАКТИРОВАТЬ: Обратите внимание, что необходимо, чтобы useEffect имел свежие копии этих функций, так как эти функции должны получить доступ к некоторой свежей современной переменной state.

ПРИМЕЧАНИЕ:

Этот код вызывает следующее предупреждение об ошибке на CodeSandbox. Хотя работает просто отлично.

React Hook React.useEffect отсутствует зависимость: 'someFunction'. Либо включите его, либо удалите массив зависимостей. (Реагирующие крючки / исчерпывающий-Deps) eslint

Сценарий реального случая:

Это упрощенный пример. В моем случае это страница поиска товара с фильтрами компонентов. Поэтому, когда я нажимаю на фильтр, чтобы активировать его (скажем, price <= 50), я запускаю useEffect(), который «слушает» переменную состояния activePriceFilters. Затем этот эффект вызывает функцию (someFunction в примере), которая вычислит filteredList и установит новое состояние productList с новым filteredList.

SNIPPET

function App() {
  
  const [someState, setSomeState] = React.useState(0);
  const [someTrigger, setSomeTrigger] = React.useState(false);
  
  function someFunction() {
    return someState + 1;  
  }
  
  React.useEffect(() => {
  
    const newState = someFunction();
    setSomeState(newState);
  
  },[someTrigger])
  
  return(
    <React.Fragment>
      <div>I am App</div>
      <div>My state: {someState}</div>
      <button onClick={()=>setSomeTrigger((prevState) => !prevState)}>Click</button>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>

Ответы [ 2 ]

1 голос
/ 02 июля 2019

Решение об определении функции внутри или вне useEffect зависит от того, где вызваны все функции.

Если ваша функция вызывается только из useEffect, то имеет смысл определить ее внутри useEffect.

Однако эта же функция вызывается изнутри useEffect, а также из других обработчиков событий или других эффектов, вам нужно определить ее вне useEffect

PS.в вашем случае вы просто обновляете состояние, для которого вам не нужно определять отдельную функцию

function App() {
  
  const [someState, setSomeState] = React.useState(0);
  const [someTrigger, setSomeTrigger] = React.useState(false);
  

  React.useEffect(() => {
    setSomeState(oldState => oldState + 1);
  
  },[someTrigger])
  
  return(
    <React.Fragment>
      <div>I am App</div>
      <div>My state: {someState}</div>
      <button onClick={()=>setSomeTrigger((prevState) => !prevState)}>Click</button>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>

Что касается вашего сценария, вы бы написали его как

useEffect(() => {
    const calcVal = (oldState) => {
         // calculate previous state based on oldState
    }

    setSomeState(calcVal);
}, [activePriceFilters])
1 голос
/ 02 июля 2019

Установка другого состояния вообще не должна влиять.

 const [someState, setSomeState] = React.useState(0);

 function increaseState() {
    setSomeState(someState + 1);
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...