Redux存储更改后,React组件不会更新

时间:2020-11-12 09:17:01

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

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

我可能错误地使用了useEffects。您如何在useEffects中使用Redux?我想为组件设置加载状态,但是由于组件仅调度一个操作来获取项目(而不是直接调用API),因此它不知道何时获取数据和更新存储,以便将其拉出

有人可以帮忙弄清楚如何在传奇获取和随后的商店更新之后更新items对象吗?

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);

非常感谢您!

1 个答案:

答案 0 :(得分: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;
  };
相关问题