Понимание асинхронного рендеринга React - PullRequest
3 голосов
/ 13 марта 2019

Я новичок в изучении React, и мне интересно, почему следующий код не работает должным образом. Я думал, что он будет отображать The numbers: 0123, но он отображает только 0. Я также использовал тот же подход с компонентом, основанным на классе, и с использованием хуков, и я все еще получаю тот же результат. Что я не понимаю с рендерингом реакции с использованием асинхронного кода?

import React from "react";
import ReactDOM from "react-dom";

function App() {
  let numbers = [0];

  fetch("some.url")
    .then(res => res.json())
    .then(list => {
      for (let n of list) {
        numbers.push(n);
      }
    });

  return <div className="App">The numbers: {numbers}</div>;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Ответы [ 3 ]

2 голосов
/ 13 марта 2019

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

Пример

const { useState, useEffect } = React;

function getNumbers() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve([1, 2, 3, 4, 5]);
    }, 1000);
  });
}

function App() {
  const [numbers, setNumbers] = useState([0]);

  useEffect(() => {
    getNumbers().then(list => {
      setNumbers(numbers => [...numbers, ...list]);
    });
  }, []);

  return <div className="App">The numbers: {numbers.join(", ")}</div>;
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
1 голос
/ 13 марта 2019

Это функциональный компонент или stateless компонент.У него нет своего государства.Поэтому, если вы измените значение переменной numbers, не изменится состояние компонента.Если вы действительно хотите использовать функциональный компонент, вы должны написать логику извлечения URL-адреса и обновления состояния в родительском компоненте с состоянием и передать переменную numbers в качестве опоры для компонента без состояния.

В противном случаеесли вам не нужно использовать функциональный компонент.Измените его на компонент класса, поместите переменную numbers в качестве параметра состояния и измените его с помощью метода setState(), и все должно работать как положено.

Я рекомендую эту статью: https://medium.com/@Zwenza/functional-vs-class-components-in-react-231e3fbd7108

Подсказка: функциональный компонент теперь может иметь состояние через хуки: https://reactjs.org/docs/hooks-intro.html

1 голос
/ 13 марта 2019

Ваш код печатает 0, потому что это значение переменной number во время рендеринга.

Вы используете следующий код:

fetch("some.url")
    .then(res => res.json())
    .then(list => {
      for (let n of list) {
        numbers.push(n);
      }
    });

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

Если вы хотите обновить его, вы должны поместить свой номер переменной в state и использовать setState() для передачи нового значения.

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

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