【问题标题】:React component does not update after Redux store changesRedux 存储更改后 React 组件不更新
【发布时间】:2021-02-24 06:54:46
【问题描述】:

我正在尝试使用 useEffect 钩子在反应组件中获取一些数据。在初始渲染之后,fetchItems() 获取项目并更新商店。但是,items 即使在 store 更新后仍然是一个空对象。

我可能用错了useEffects。你如何将 Redux 与 useEffects 一起使用?我想为组件设置一个加载状态,但是由于组件只调度一个动作来获取项目(而不是直接调用 API),它不知道何时获取数据并更新存储,因此它可以拉它.

有人可以帮忙弄清楚如何确保items 对象在 saga fetch 和后续商店更新之后更新吗?

import React, { useState, useEffect } from "react";
import { connect } from 'react-redux';
import { useParams } from "react-router-dom";

const ItemComponent = ({ item, fetchItem }) => {
    const { itemId } = useParams();
    
    const [isLoading, setIsLoading] = useState(false);

    useEffect(() => {
        setIsLoading(true)
        fetchItem(itemId)
        setIsLoading(false)
    }, []);
    
    console.log(item) // gives empty object even after the fetch and store update
}

const mapStateToProps = (state) => {
  return {
    item: state.item
  }
}

const mapDispatchToProps = (dispatch) => {
    return {
        fetchItem: (itemId) => { dispatch(fetchItemActionCreator(itemId)) }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(ItemComponent);
  • fetchItemActionCreator 是一个动作创建者,用于创建要分派的动作。
  • 我的 reducer 和 saga 工作正常,因为我可以在控制台中看到存储操作和更新。
  • 如果我将items 对象传递到useEffect 的依赖数组中,则会出现无限循环并且页面不断重新渲染。

减速机:

const itemReducer = (state={}, { type, payload }) => { 
  switch(type) { 
  case ITEM_GET_SUCCESS: 
    return {...state, ...payload} 
  default: return state 
  } 
} 

fetchItemActionCreator:

import { createAction } from '@reduxjs/toolkit';

export const fetchItemActionCreator = createAction(ITEM_GET_PENDING);

非常感谢您!

【问题讨论】:

  • 你能分享你的item reducerfetchItemActionCreator
  • const ItemComponent = ({ item , fetchItem}) => { 这是偶然的吗?
  • 刚刚添加了reducer和action creator。是的,fetchItem 不小心没有添加到问题中

标签: redux react-redux redux-saga use-effect


【解决方案1】:

我想为组件设置一个加载状态

/** Action */
const getItem = () => dispatch => {
  dispatch({ type: 'GET_ITEM_START' });

  axios
    .get('your api end point')
    .then(res => {
      const item = res.data;
      dispatch({
        type: 'GET_ITEM_SUCCESS',
        payload: {
          item,
        },
      });
    })
    .catch(error => {
      dispatch({
        type: 'GET_ITEM_FAIL',
        payload: error,
      });
    });
};

/** Reducer */
const INITIAL_STATE = {
  item: null,
  error: '',
  loading: false,
};

const itemReducer = (state = INITIAL_STATE, { type, payload }) => {
  switch (type) {
    case 'GET_ITEM_START':
      return { ...state, error: '', loading: true };

    case 'GET_ITEM_SUCCESS':
      return { ...state, ...payload, loading: false };

    case 'GET_ITEM_FAIL':
      return { ...state, error: payload, loading: false };

    default:
      return state;
  }
};

然后你就可以在你的组件中处理加载状态了

  const ItemComponent = ({ fetchItem, item, loading, error }) => {
    /** ... */
    /**
      Check for loading and show a spinner or anything like that
    */

    useEffect(() => {
      fetchItem(itemId);
    }, []);

    if (loading) return <ActivityIndicator />;
    if (item) return <View>{/* renderItem */}</View>;
    return null;
  };

【讨论】:

  • 感谢您分享此@Hend El-Sahli。有没有办法用useEffect 做到这一点?您是否需要在组件本身中提取数据?
  • 感谢您的更新,@Hend El-Sahli。我想知道,我不需要将itemId传递给useEffect的依赖数组吗?
猜你喜欢
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 2020-04-07
相关资源
最近更新 更多