React Hooks状态不更新视图中的变量

时间:2020-01-24 18:00:58

标签: reactjs axios react-hooks

我正在尝试设置一个状态,该状态是我从API以数组形式获取的。

以各种可能的方式进行尝试,不起作用。

关于如何解决此问题的任何想法?

实例是axios.create,它将实例创建到具有CORS-ALLOW-CROSS-ORIGIN True

的本地主机django服务器
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 个答案:

答案 0 :(得分:1)

这样做,

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;

答案 1 :(得分:1)

这似乎是useEffect挂钩的好用例。另外,您需要等待useEffect语句中的异步函数。 useEffect挂钩本身不能是异步函数。同样,原始实现将导致无限循环。 setState函数将触发重新渲染,然后再触发fetch函数再次触发。请考虑以下内容:

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;

答案 2 :(得分:0)

根据你们的建议,我想出了下面的代码,到目前为止效果很好。

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;