Состояние React Hooks не обновляет переменную в поле зрения - PullRequest
1 голос
/ 24 января 2020

Я пытаюсь установить состояние, которое я получаю из API в виде массива.

Пробовал это всеми возможными способами, не работает.

Любое идеи о том, как это исправить?

экземпляр - это axios.create, который создает экземпляр на сервере localhost django, который имеет CORS-ALLOW-CROSS-ORIGIN True

import React, { useState } from "react";
import { instance } from "../../stores/instance";

const OneList = () => {
  const [one, setOne] = useState([]);
  const fetchText = async () => {
    const response = await instance.get(`/one/list/`);
    setOne(response.data);
  };
  fetchText();
  return (
    <>
      <div>Hello World.</div>
      {one.forEach(o => (
        <p>o.text</p>
      ))}
    </>
  );
};
export default OneList;

Ответы [ 3 ]

1 голос
/ 24 января 2020

Это хороший вариант использования для useEffect hook. Также вам нужно дождаться асинхронных c функций внутри оператора useEffect. Хук useEffect сам по себе не может быть асин c функцией. Кроме того, оригинальная реализация привела бы к бесконечному l oop. Функция setState запускает повторную визуализацию, которая затем запускает функцию выборки снова. Учтите следующее:

import React, { useState, useEffect } from "react";
import { instance } from "../../stores/instance";

const OneList = () => {
  const [one, setOne] = useState([]);

  const fetchText = async () => {
    const request= await instance.get(`/one/list/`);
    request.then( r => setOne(r.data))
  };

  useEffect(() => {
    (async () => {
      await fetchText();
    })();
  }, []);

  return (
    <>
      <div>Hello World.</div>
      {one.forEach(o => (
        <p>o.text</p>
      ))}
    </>
  );
};
export default OneList;

1 голос
/ 24 января 2020

Сделай так,

import React, { useState } from "react";
import { instance } from "../../stores/instance";

const OneList = () => {
  const [one, setOne] = useState([]);
  const fetchText = async () => {
    const response = await instance.get(`/one/list/`);
    setOne(response.data);
  };

  useEffect(() => {
    fetchText();
  },[ any variable you want it to fetch that again ]);



  return (
    <>
      <div>Hello World.</div>
      {one.forEach(o => (
        <p>o.text</p>
      ))}
    </>
  );
};
export default OneList;
0 голосов
/ 25 января 2020

По совету вас, ребята, я придумал приведенный ниже код, который пока отлично работает.

import React, { useState, useEffect } from "react";
import { instance } from "../../stores/instance";

const OneList = () => {
  const [one, setOne] = useState([]);
  const [el, setEl] = useState(null);

  const fetchText = async () => {
    let res = await instance.get("/one/list/");
    setOne(res.data);
  };

  useEffect(() => {
    (async () => {
      await fetchText();
    })();
  }, []);
  useEffect(() => {
    const handleClick = e => {
      let newEl = document.createElement("input");
      newEl.value = e.target.innerHTML;
      newEl.id = e.target.id;
      newEl.addEventListener("keypress", e => handleInput(e));
      newEl.addEventListener("focusout", e => handleInput(e));
      e.target.parentNode.replaceChild(newEl, e.target);
      newEl.focus();
    };
    const handleInput = async e => {
      console.log(e.type);
      if (
        e.target.value !== "" &&
        (e.key === "Enter" || e.type === "focusout")
      ) {
        let payload = { text: e.target.value };
        try {
          e.preventDefault();
          let res = await instance.put(`/one/update/${e.target.id}`, payload);
          let text = res.data.text;
          e.target.value = text;
          let newEl = document.createElement("span");
          newEl.innerHTML = text;
          newEl.addEventListener("click", e => handleClick(e));
          newEl.id = e.target.id;
          e.target.parentNode.replaceChild(newEl, e.target);
        } catch (e) {
          console.error(e);
        }
      }
    };

    setEl(
      one.map(o => (
        <p>
          <span id={o.id} onClick={e => handleClick(e)}>
            {o.text}
          </span>
        </p>
      ))
    );
  }, [one]);

  return <>{el}</>;
};

export default OneList;
...