Как react useEffect работает с useState hook?

#reactjs #use-effect

Вопрос:

Может кто-нибудь объяснить, что я делаю не так? У меня есть функциональный компонент react, в котором я использую хук useEffect для извлечения некоторых данных с сервера и приведения этих данных в состояние. Сразу после извлечения данных в том же справочнике мне нужно использовать это значение состояния, но по какой-то причине значение ясно. Взгляните на мой пример, в консоли есть пустая строка, но в браузере я вижу это значение.

 import "./styles.css";
import React, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  function fetchHello() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve("Hello World");
      }, 1000);
    });
  }

  const handleSetValue = async () => {
    const hello = await fetchHello();
    setValue(hello);
  };

  useEffect(() => {
    const fetchData = async () => {
      await handleSetValue();
      console.log(value);
    };

    fetchData();
  }, [value]);

  return (
    <div className="App">
      <h1>{value}</h1>
    </div>
  );
};

export default App;
 

Ссылка на codesandbox.

Комментарии:

1. Операция не имеет значения в массиве dep

Ответ №1:

useEffect Крюк будет запущен после рендеринга вашего компонента, и он будет перезапущен всякий раз, когда изменится одна из зависимостей, переданных в массиве второго аргумента.

В вашем эффекте вы делаете console.log(value) , но в массиве зависимостей вы не передали value как зависимость. Таким образом, эффект выполняется только при монтировании (когда value он неподвижен "" ) и никогда больше.

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

 import "./styles.css";
import React, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  function fetchHello() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve("Hello World");
      }, 1000);
    });
  }

  const handleSetValue = async () => {
    const hello = await fetchHello();
    setValue(hello);
  };

  useEffect(() => {
    const fetchData = async () => {
      await handleSetValue();
      console.log(value);
    };

    fetchData();
  }, [value]);

  return (
    <div className="App">
      <h1>{value}</h1>
    </div>
  );
};

export default App;

 

Не знаю точно, что вам нужно сделать, но если вам нужно что-то сделать с возвращенным значением из вашей конечной точки, вы должны либо сделать это с возвращенным значением конечной точки (вместо значения в состоянии), либо обработать значение состояния вне крючка

 import "./styles.css";
import React, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  function fetchHello() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve("Hello World");
      }, 1000);
    });
  }

  const handleSetValue = async () => {
    const hello = await fetchHello();

    // handle the returned value here 

    setValue(hello);
  };

  useEffect(() => {
    const fetchData = async () => {
      await handleSetValue();

    };

    fetchData();
  }, []);

  // Or handle the value stored in the state once is set
  if(value) {
    // do something
  }

  return (
    <div className="App">
      <h1>{value}</h1>
    </div>
  );
};

export default App;