Как правильно установить состояние в функциональном компоненте React? - PullRequest
0 голосов
/ 08 мая 2020

Я реализовал перехватчик состояния React в функциональном компоненте React следующим образом:

const [tableData, setTableData] = useState([]);

В моем компоненте я выполняю запрос асинхронного API и заполняю таблицу с результатом:

const loadArtikel = () =>
    fetch("https://my-api.com/api/v1/xyz")
        .then(res => (res.ok ? res : Promise.reject(res)))
        .then(res => res.json())


return (
    <Async promiseFn={loadArtikel}>
        {({ data, err, isLoading }) => {
            if (isLoading) return (<div>Loading...</div>)
            if (err) return `Something went wrong: ${err.message}`

            if (data) {
                var tempData = [];
                Object.keys(data.artikel).map(function (keyName, keyIndex) {
                    tempData.push(data.artikel[keyName]);
                });
                setTableData(tempData); // this line is causing problems
                return (
                    <MaterialTable
                        data={tableData}
                    />
                )
            }
        }}
    </Async>
);

Когда я использую setTableData(), это приводит к тому, что запрос на выборку повторяется снова и снова. Не могу сказать почему.

1 Ответ

1 голос
/ 08 мая 2020

Это фактически приводит к бесконечному l oop, так как компонент будет повторно визуализировать каждый раз, когда его свойства / состояние меняются. В этом случае вы напрямую вызываете setTableData в возврате вашего компонента, который обновляет состояние. Это, в свою очередь, приведет к повторному рендерингу компонента, что приведет к многократному вызову запроса.

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

useEffect(() => {  
  fetch('https://my-api.com/api/v1/xyz')
    .then(response => response.json())
    .then(result => {
      // process data
      const tempData = ......;
      setTableData(tempData);
    });     
}, []);


return (
  <>
  {
    tableData.length 
      ? (
        <MaterialTable
          data={tableData}
        />
      : <div>Loading...</div>
  } 
  </>
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...