reactjs useEffect使用redux时缺少依赖项useDispatch

lxkprmvk  于 2023-05-28  发布在  React
关注(0)|答案(4)|浏览(212)

我想在我的组件使用react hooks useEffect挂载时获取我的类别,而不是在每次重新渲染时。但我一直收到这个警告React Hook useEffect has a missing dependency:'dispatch'
下面是我的代码:

const categories = useSelector(state => state.category.categories);
const dispatch = useDispatch();

useEffect(() => {
    console.log('effecting');
    const fetchCategories = async () => {
       console.log('fetching');
       try {
            const response = await axios.get('/api/v1/categories');
            dispatch(initCategory(response.data.data.categories));
       } catch (e) {
           console.log(e);
       }
    }

    fetchCategories();
}, []);
v7pvogib

v7pvogib1#

您可以安全地将dispatch函数添加到useEffect依赖数组中。如果你看react-redux文档,特别是hooks部分,他们提到了这个“问题”。
方法传递相同的存储示例时,分派函数引用将是稳定的。通常,该存储示例在应用程序中从不更改。
然而,React hooks lint规则并不知道dispatch应该是稳定的,并且会警告dispatch变量应该被添加到useEffect和useCallback的依赖数组中。最简单的解决方案就是这样做:

export const Todos() = () => {
const dispatch = useDispatch();

useEffect(() => {
    dispatch(fetchTodos())
  // Safe to add dispatch to the dependencies array
  }, [dispatch])

}

q5iwbnjs

q5iwbnjs2#

dispatch添加到依赖数组(当前为空)。

useEffect(() => {
    console.log('effecting');
    const fetchCategories = async () => {
       console.log('fetching');
       try {
            const response = await axios.get('/api/v1/categories');
            dispatch(initCategory(response.data.data.categories));
       } catch (e) {
           console.log(e);
       }
    }

    fetchCategories();
}, [dispatch]);
ffx8fchx

ffx8fchx3#

这可能是一个被忽视的承诺的问题。

fetchCategories() returns a promise.

你可以试试

useEffect(() => {
    const fetchCategories = async () => {
       try {
            const response = await axios.get('/api/v1/categories');
            await dispatch(initCategory(response.data.data.categories));
       } catch (e) {
           console.log(e);
       }
    }

    fetchCategories().then(res => (console.log(res());
}, []);
ehxuflar

ehxuflar4#

原因:

useEffect钩子的依赖数组中包含dispatch的原因是为了确保在效果中使用正确和最新的dispatch函数。
在某些情况下,从Redux商店获得的dispatch函数可以在组件的生命周期中更改。例如,如果您使用Redux Thunk或Redux Saga 等中间件,则中间件可能会修改dispatch函数以处理异步操作。
通过在依赖数组中包含dispatch,你告诉React每当dispatch函数更改时重新运行效果。这可确保您始终在效果中使用最新的dispatch函数。

添加dispatch而不是reducer函数作为依赖示例:

import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { initCategory } from '../redux/actions/categoryActions';
import axios from 'axios';

const CategoryComponent = () => {
  const dispatch = useDispatch();

  useEffect(() => {
    const fetchCategories = async () => {
      try {
        const response = await axios.get('/api/v1/categories');
        dispatch(initCategory(response.data.data.categories));
      } catch (error) {
        console.log(error);
      }
    };

    fetchCategories();
  }, [dispatch]);

  // Rest of the component code

  return (
    <div>
      {/* Component JSX */}
    </div>
  );
};

export default CategoryComponent;

在这个例子中,CategoryComponent从API中获取类别,并分派一个action initCategory来更新Redux中的类别状态。useDispatch钩子用于从Redux商店获取调度函数。
为了确保在效果中使用正确的调度函数,我们在useEffect钩子的依赖数组中包含调度。这告诉React在调度函数发生变化时重新运行效果,确保在调度动作时使用最新的调度函数。
在依赖数组中包含分派可以确保效果正确工作,即使分派函数由于中间件或其他因素而更改。我们在依赖数组中包含dispatch而不是initCategory的原因是因为dispatch函数可能会随着时间的推移而改变,而initCategory是对action creator函数的稳定引用。
在依赖数组中包含initCategory将导致每次组件重新呈现时重新运行效果,即使initCategory没有更改。这可能会导致不必要的效果重新执行,并可能导致性能问题。
另一方面,分派从Redux商店获得,并且如果商店的配置或中间件设置改变,则分派可能改变。通过在依赖数组中包含dispatch,我们可以确保只有当dispatch函数本身发生变化时才会重新运行效果,这正是我们想要的行为。

派单变更示例:

import { createStore } from 'redux';

// Reducer function
function counterReducer(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    default:
      return state;
  }
}

// Create the store
const store = createStore(counterReducer);

// Dispatch an action
store.dispatch({ type: 'INCREMENT' });

// Update store's configuration
store.replaceReducer((state = 0, action) => {
  switch (action.type) {
    case 'DOUBLE':
      return state * 2;
    default:
      return state;
  }
});

// Dispatch an action using the updated store
store.dispatch({ type: 'DOUBLE' });

在典型的Redux设置中,dispatch函数是从store中获取的,而store是使用Redux的createStore函数创建的。虽然分派函数本身在应用程序的生命周期中不会更改,但在某些情况下,商店的配置或中间件设置可能会更改,从而导致创建分派函数的新示例。在本例中,我们首先使用createStore函数创建一个存储,并定义一个基本的计数器缩减器。然后我们分派一个动作来增加计数器。
接下来,我们使用replaceReducer方法更新存储的配置,该方法将现有的reducer替换为一个新的reducer,该新的reducer在分派'DOUBLE'操作时将状态值加倍。
在更新存储的配置之后,我们使用更新后的存储分派一个“DOUBLE”动作,触发新的reducer逻辑。
正如您所看到的,存储的配置发生了更改,导致创建了一个新的调度函数示例。在这种情况下,在依赖于存储的配置改变的效果的依赖性阵列中包括分派将确保当分派函数被更新时重新运行效果。

相关问题