如何分发useEffect?

时间:2020-09-10 19:34:39

标签: javascript reactjs use-effect use-state use-reducer

我尝试在useState内使用useEffect设置状态,没有问题,代码如下:

import React, {useState, useEffect} from 'react';

const Banner = () => {
  const [title, setTitle] = useState([]);
  
  useEffect(() => {
    async function fetchData() {
      const api = 'some api url';
      let response = await fetch(api);
      response = await response.json();
      setTitle(response.title);
    }
    fetchData();
  })
}

export default Banner;

现在我想做同样的事情,但是使用useReducer,我试图将上面的代码修改为以下代码,但是没有运气:

import React, {useState, useEffect} from 'react';

const bannerReducer = (state, action) => {
  switch(action.type) {
    case 'setTitle':
      return {
        ...state,
        title: state.title
      }
  }
}

const [state, dispatch] = useReducer(bannerReducer, {title: []});

const Banner = () => {
  const [title, setTitle] = useState([]);

  useEffect(() => {
    async function fetchData() {
      const api = 'some api url';
      let response = await fetch(api);
      response = await response.json();
      dispatch({type: 'setTitle', response.title});
    }
    fetchData();
  })
}

export default Banner;

在这种情况下如何使用useReducer?

2 个答案:

答案 0 :(得分:0)

您的useReducer调用不在函数内,因此未附加到该函数。 像这样称呼它:

const Banner = () => {
  const [title, setTitle] = useState([]);
  const [state, dispatch] = useReducer(bannerReducer, {title: []});

  useEffect(() => {
    async function fetchData() {
      const api = 'some api url';
      let response = await fetch(api);
      response = await response.json();
      dispatch({type: 'setTitle', response.title});
    }
    fetchData();
  }, []);
}

还请记住,每次调用useEffect函数时,您的Banner都会运行。考虑按照钩子教程中的说明添加依赖项数组:https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects

答案 1 :(得分:0)

您正在使用与以前相同的state属性设置reducer,在这种情况下,您基本上是在做以下事情:

title: state.title

由于您的默认状态是带有空数组值的标题,因此您无需进行任何更改。

您需要在减速器中使用action参数来完成所需的操作:

const bannerReducer = (state, action) => {
 switch(action.type) {
  case 'setTitle':
   return {
    ...state,
    title: action.title
   }
  }
}

您的调度应该是这样的:

dispatch({type: 'setTitle', title: response.title});