Redux:根据操作在Reducer中更改初始状态的不同部分

问题描述

我有以下Reducer:

const initialState = {}

const dishreducer = (state = initialState,action) => {
    switch (action.type) {
      case 'LOAD_disHES': 
        return (action.dishes)
    
      case 'LOAD_disHES_ERROR': 
        console.log("load dishes error")
        return state
      case 'LOAD_disHES_SUCCESS': 
        console.log("load dishes success")
        return state
      default:
        return state;
    }
  };

  export default dishreducer;

以及以下操作:

import {database} from '../../config/fbConfig'

export const startLoadingdishes = (dishes) => {
    return (dispatch) =>{
        return database.ref('products-dishes').once('value').then((snapshot) => {
            let dishes = {}
            snapshot.forEach((childSnapshot) => {
                let parentkey = childSnapshot.key
                let dishArray = [];
                childSnapshot.forEach((dish) =>{
                        dishArray.push(dish.val())
                    });
                dishes[childSnapshot.key] = dishArray;
            })
    
            dispatch(loaddishes(dishes))
        }).then(() => {
            dispatch({ type: 'LOAD_disHES_SUCCESS' });
          }).catch(err => {
            dispatch({ type: 'LOAD_disHES_ERROR' },err);
          });
    }

}

export const loaddishes = (dishes) => { 
    return {
        type: 'LOAD_disHES',dishes               
    }
}

在特定组件的componentDidLoad()内部调用“ startLoadingdishes”操作。但是,我想更改dishreducer的初始状态,以使其包含其他信息,如下所示:

const initialState = {
    value : {},loaded: false,loading: false,error: false
}

因此,现在应将由reducer返回的“ action.dishes”(在“ LOAD_disHES”情况下)放置在状态的“值”部分内,而不是整个状态。同样,如果菜肴早已加载,则状态的“已加载”部分应设置为true,依此类推。我知道这很简单,但是由于我是React + Redux的新手,所以我不知道如何正确更改Action / Reducer代码(同时保持状态不变)。任何帮助表示赞赏。

解决方法

我最初问的是问题,这是我的解决方法(不确定这是否是“最佳”方法):

新的reducer文件:

const initialState = {
    value : {},loaded: false,loading: false,error: false
}

const dishReducer = (state = initialState,action) => {
    switch (action.type) {
      case 'LOAD_DISHES': 
        return {
          value: action.dishes,loading: !state.loading,//this might need to be set to true
          error: false
        }
    
      case 'LOAD_DISHES_ERROR': 
        console.log("load dishes error")
        return {
          ...state,//or: state.value,as the other parts of state are being overwritten below
          loaded: false,error: true
        }
      case 'LOAD_DISHES_SUCCESS': 
        console.log("load dishes success")
        return { 
          ...state,//better: state.value
          loaded: true,error: false
        }
      default:
        return state;
    }
  };

  export default dishReducer;

动作文件无变化。

现在,在“主要”组件内部,我最初是这样访问状态的:

class Main extends Component {

  componentDidMount() { 
    this.props.startLoadingDishes();
  }

  render() {

    return (
      //some code
    )
  }
}

const mapStateToProps = (state) => {
  return {
    dishes: state.dishes  //to access dishes: dishes.value
  }
}

export default connect(mapStateToProps,actions)(Main)

Main组件代码也保持不变,不同之处在于,我现在使用'dishes.value'而不是'dishes'来从状态中访问菜品的价值(而dishs.loaded为已加载,依此类推) )。现在componentDidMount内部的动作调用者如下:

componentDidMount() { 
    if(!this.props.dishes.loaded){
      this.props.startLoadingDishes();
      console.log("loading dishes from database")
    }
  }