繁体   English   中英

Redux:根据Actions改变Reducer中初始state的不同部分

[英]Redux: altering different parts of the initial state in Reducer according to Actions

我有以下减速器:

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               
    }
}

'startLoadingDishes' 动作在某个组件的 componentDidLoad() 内部被调用。 但是,我想更改我的 dishReducer 的初始 state,以便它包含其他信息,如下所示:

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

所以现在 reducer 返回的 'action.dishes' [在 'LOAD_DISHES' 情况下] 应该放在 state 的 'value' 部分,而不是整个 state。此外,state 的 'loaded' 部分应该是如果菜肴已经提前加载,则设置为 true,依此类推。 我知道这很简单,但由于我是 React+Redux 的新手,我不知道如何正确更改 Action/Reducer 代码(同时保持 state 不变性)。 任何帮助表示赞赏。

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

新的减速器文件:

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,
          loaded: false,   //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,
          loading: false,
          error: true
        }
      case 'LOAD_DISHES_SUCCESS': 
        console.log("load dishes success")
        return { 
          ...state,  //better: state.value
          loaded: true,
          loading: false,
          error: false
        }
      default:
        return state;
    }
  };

  export default dishReducer;

动作文件没有变化。

现在,在“主要”组件中,我最初是这样访问 state 的:

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)

主要组件代码也保持不变,不同之处在于现在我使用“dishes.value”而不是“dishes”来访问 state 中的盘子值(dishes.loaded 表示已加载,等等)。 现在 componentDidMount 中的动作调用者如下:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM