【问题标题】:Redux: altering different parts of the initial state in Reducer according to ActionsRedux:根据 Actions 改变 Reducer 中初始状态的不同部分
【发布时间】:2020-09-21 20:35:33
【问题描述】:

我有以下 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               
    }
}

'startLoadingDishes' 动作在某个组件的 componentDidLoad() 中被调用。但是,我想更改我的 discReducer 的初始状态,以便它包含附加信息,如下所示:

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

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

【问题讨论】:

    标签: javascript reactjs redux redux-reducers


    【解决方案1】:

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

    新的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,
              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;
    
    

    动作文件没有变化。

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

    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”来从状态访问菜肴的值(并且为加载而使用 discs.loaded,等等)。现在componentDidMount里面的action caller如下:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 2019-11-22
      • 2016-02-18
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      相关资源
      最近更新 更多