Почему мое обещание неправильно устанавливает мое состояние? - PullRequest
2 голосов
/ 20 октября 2019

У меня есть интерфейс React, который вызывает мой Rails-сервер, и я пытаюсь написать обещание, которое выполняется на этом. Однако я не понимаю, что не так с обещанием, которое я написал. Я вижу, что сервер отвечает OK, однако у меня возникают проблемы при настройке состояния моего компонента для данных, которые я получаю

const [things, setThings] = useState([])

useEffect(() => {
    fetchThings();
}, [])

function getThingsPromise(){
    return new Promise((resolve, reject) => {
        const url = "/api/v1/things/index";
        fetch(url).then(response => {
            if (response.ok) {
                return response.json();
            }
            throw new Error('Network response was not ok.');
        }).then(response => resolve(response))
    })
}

function fetchThings() {
    getThingsPromise().then((response) => {
        setThings(response)
    })
    console.log(things)
}

1 Ответ

1 голос
/ 20 октября 2019

На самом деле у вас нет проблем с настройкой данных, вы просто помещаете файл console.log в неправильное место.
Установка состояния реакции происходит асинхронно. На момент регистрации вашего состояния оно еще не обновлялось полученными данными. Он будет доступен в следующий раз, когда компонент перезапустится, но тогда ваша функция fetchThings () не будет выполнена, поэтому вы не увидите журнал.
Вы можете наблюдать это, если поместите console.log в компонентвместо body:
Сначала при рендеринге будет записано все еще пустое состояние, затем после получения данных состояние обновляется, что приводит к повторной визуализации компонента. Во втором рендере будут доступны данные.

function App() {
  const [things, setThings] = useState([]);

  useEffect(() => {
    fetchThings();
  }, []);

  function getThingsPromise() {
    return new Promise((resolve, reject) => {
      const url = "/api/v1/things/index";
      fetch(url)
        .then(response => {
          if (response.ok) {
            return response.json();
          }
          throw new Error("Network response was not ok.");
        })
        .then(response => resolve(response));
    });
  }

  function fetchThings() {
    getThingsPromise().then(response => {
      setThings(response);
    });
    console.log("The state hasn't been updated yet:", things);
  }

  // this logs the state every time the component renders
  console.log("First it's empty, then we have data:", things);

  return <div>result: {JSON.stringify(things)}</div>;
}

Вы можете использовать этот пример здесь: https://codesandbox.io/s/hooks-setstate-log-hjle1?fontsize=14

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...