【问题标题】:React-Redux, how to subscribe to changes in state and apply actionsReact-Redux,如何订阅状态变化和应用动作
【发布时间】:2018-03-22 20:01:48
【问题描述】:

我正在使用 react、redux 和 material-ui 构建一个网格和一个过滤器组件

这是我在 redux 中的过滤器状态对象的样子

{
   1: {id:1, name:'firstName', value:'John'}
   2: {id:2, name:'LastName', value:'Doe'}
}

商店中的物品对象

{
   12: {id:12, firstName:'John', lastName:'Doe', contact:''}
   13: {id:13, firstName:'Mark', lastName:'Doyle', contact:''}
 }

当商店中过滤器对象的状态发生变化时,我想执行 applyFilters 函数来缩小项目范围。订阅状态对象中的更改并执行操作以更新商店中另一个对象的状态的最佳模式是什么?还是有更好的方法来解决这个问题?

当前实施

我不确定这是否是在动作创建者中访问状态的反模式。

export function updateFilters(namespace, filter, filterText) { 

    return (dispatch, getState) => {
        // To update filters object in the store
        dispatch({
            type: `${namespace}/${UPDATE_FILTERS}`,
            value: filterText,
            payload: filter.get('id')
        })

        //Actual filtering
        let state = getState();
        let filters = state[`${namespace}`].filters;
        let items = state[`${namespace}`].items;
        let filteredItems = applyFilters(items, filters);

        // To update filteredItems in the store
        dispatch({
            type: `${namespace}/${APPLY_FILTERS}`,
            payload: filteredItems
        })
    }   
}

【问题讨论】:

  • 我绝对建议将所有状态操作留在减速器中。不过,我实际上并没有看到您在哪里更新状态。这是否发生在 applyFilters() 中?

标签: react-native redux react-redux


【解决方案1】:

更新的答案提供了您的反馈并添加了上下文。您可以从 reducer 中分派第二个操作,将您的过滤器对象作为参数传递。

例如:

function reducer1(state = initialState, action) {
    switch (action.type) {
       case UPDATE_ITEMS:
          +//dispatch 2nd action and pass filtered object as parameter
          +//the 2nd action can update the item object
          -//update items object
       default:
          return state
    }
}

这里有很多来回,所以我将详细说明我将如何执行此操作的示例,假设您希望填充一次存储并在之后处理内存中的对象。

事件处理程序:

handleFilterChange = (filterText) => {
    this.props.updateFilter(filterText);
}

行动:

export function updateItem(filterText) {
    // you could dispatch another action, but not sure why you would
    return { 
        type: UPDATE_FILTER, filterText, 
    };
}

减速机:

function updateFilterAndItem(state = initialState, action) {
    switch (action.type) {
        case UPDATE_FILTER:
            {
                const newItems = state.items.filter(text => state.items.includes(action.filterText));
                return Object.assign(
                    {}, 
                    state, 
                    { 
                        items: newItems,
                        filter: action.filterText
                    });
            }
    }
}

这是我可以根据您正在尝试做的事情为您提供的最接近的答案,但我会要求您重新考虑这一点。为什么要在 redux 存储中保留过滤文本?每次调用事件处理程序时,整个文本字符串无论如何都会向下传递到堆栈中。我想尽我所能根据 StackOverflow 的指导方针回答你的问题,但我也想挑战你思考你的实现,以及是否有一种简单的方法可以实现你想要的结果。

【讨论】:

  • 我在 redux 商店中同时拥有过滤器和项目。当 filter 的值发生变化时,将调用一个 action creator,然后一个 reducer 会更新 redux 存储中 filters 对象中的相应值。我正在尝试的是在发生这种情况时触发一个函数并更新 redux 商店中的 items 对象
  • 我不确定这是否回答了您最初的问题,但为什么不直接使用过滤器再次查询数据,或者对内存中的对象使用过滤器?你想要一个例子吗?
  • 存储中的Items对象是在初始加载时创建的,每次过滤器发生时,存储在redux存储中的数据都会根据应用的过滤器值缩小范围。所以我不查询以获取有关过滤器操作的数据。我在这里尝试的是在 redux 中维护过滤器的状态,并且每当过滤器对象发生状态更改时,将操作应用于商店中的项目
  • 感谢您的回复。目前在我的过滤器操作方法中,我分派了两次,一次用于更新过滤器,另一次用于使用 redux-thunk 更新项目,我的代码目前看起来接近您提供的内容。我正在检查而不是从操作方法触发同步调度,如果有更好的方法可以通过直接订阅而不需要两次往返来根据对另一个对象状态的更改来更新一个对象的状态
猜你喜欢
  • 2017-08-03
  • 2018-04-08
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多