UseEffect 返回后用 useState 初始化:这可能吗?

时间:2021-03-28 05:05:37

标签: reactjs use-effect

我有两个 React 问题。

使用 useEffect 我正在调用一个 api:

React.useEffect(() => {
  //API get call
},[]);

api 的结果存储在数组中。

问题 1:我知道 useEffect 是异步方法,但是有什么方法可以让我在 useEffect 返回后使用 useState 来初始化 dropdown 的值?

问题 2:如何使用数组的值初始化 forEach 循环内部的值?

3 个答案:

答案 0 :(得分:1)

useEffect 中的 API 调用之后,调用您要保存到的 useState 的设置状态。例如:

const [state, setState] = useState([]);

const someFetch = async () => {
 // using JS fetch API
 const result = await fetch("getFetchSomeData");
 // assuming the state is in the form of an array
 setState(result.json())
}

useEffect(() => }{
   someFetch();
});

return (
  // rendering the array of fetched state this will update on next render after fetch
  <div>{state}</div>
):

答案 1 :(得分:1)

问题 1

我可能会这样做:

function MyComponent() {
  const [isLoading, setIsLoading] = useState(false);
  const [data, setData] = useState(undefined);
  
  useEffect(() => {
    async function getData() {
      setIsLoading(true);
      const data = await /* API call */
      setData((prevVal) => data);
      setIsLoading(false);
    }

    getData();
  }, []);
  
  if (loading) return <h1>Loading...</h1>;

  if (!loading && !data) return <h1>Error!</h1>;

  return (
    /* your component */
  );
}

本质上,您必须解决钩子的“异步”方面。

问题 2

您没有说明要初始化什么,但我假设某种组件需要来自 API 的值。以下示例使用 HTML select 元素。使用 map()

<select>
{
  data && data.map(({value, label}, index) => (
    <option key={index} value={value}>{label}</option>
  ))
}
</select>

答案 2 :(得分:0)

<块引用>

问题 1:我知道 useEffect 是异步方法,但是有什么方法可以让我在 useEffect 返回后使用 useState 来初始化 dropdown 的值?

不,我们不能在 useEffect 运行后初始化 useState。 useEffect 钩子总是在第一次渲染之后和每次更新之后运行。我们还需要在第一次渲染时为状态提供初始化值。然后当 useEffect 运行时,我们可以简单地通过设置它来更新状态。

function App(){

 const [stateVariable, setStateVariable] = useState(null);
 
 useEffect(() => {

   async function fetchApiCall(){
    fetch('http://example.com/movies.json')
       .then(response => response.json())
       .then(data => setStateVariable(data));
   }
  fetchApiCall(); // function call

 },[]);

}

<块引用>

问题 2:如何使用数组的值初始化 forEach 循环中的值?

现在我们的 stateVariable 中有我们的数据。很可能来自 API 的数据位于对象数组 [JSON] 中。

Array.prototype.map() 函数在这里可能会有所帮助。根据 mdn docs

<块引用>

map() 方法创建一个新数组,其中填充了对调用数组中的每个元素调用提供的函数的结果。


function processEachElement(element, index){
  return <li key={index}>{element}</li>;
}

const newData = data.map(processEachElement);
// Now the newData is an array of `JSX.Elements`. Remember, not an array of objects.

所以,最终代码如下,

function App() {
  const [stateVariable, setStateVariable] = useState(null);

  useEffect(() => {
    async function fetchApiCall() {
      fetch("http://example.com/movies.json")
        .then((response) => response.json())
        .then((data) => setStateVariable(data));
    }
    fetchApiCall(); // function call
  }, []);

  function processEachElement(element, index) {
    return <li key={index}>{element}</li>;
  }

  const newData = data.map(processEachElement);

  return <ul>{newData}</ul>;
}