设计Reux可重用组件的动作和缩减器

问题描述:

我正在开发一个使用Redux和React的大型应用程序,并决定制作一些可重用的组件,如自定义复选框和单选按钮。设计Reux可重用组件的动作和缩减器

因为我想将这些信息存储在Redux存储中,以便能够轻松地调试应用程序的状态,并且同一组件在任何地方都具有相同的功能,为每个组件创建减速器和操作似乎是个不错的主意。

但是,Redux reducer返回一个新的状态并将其以reducer的名称作为关键字保存在存储中,并且禁止在同一页面中使用相同的动作和reducer而保留相同类型的多个组件不同的州。

我认为有两个解决此问题:

  • 创建,我使用的每个组件不同的操作和减速器,甚至认为该组件,它的功能是相同的。这个解决方案似乎不是一个好的解决方案,因为会有很多冗余的代码。

  • 创建具有足够参数的操作,以便能够区分reducer中的每个参数,并且只更改指定的状态部分。

我继续第二个选项。

操作文件中为CheckBox组件:

import {createAction} from 'redux-actions'; 

/****** Actions ******/ 
export const CHANGE_CHECKBOX_STATE = "CHANGE_CHECKBOX_STATE"; 

/****** Action creators ******/ 
export const changeCheckboxState = createAction(CHANGE_CHECKBOX_STATE, (block, name, state) => { 
    return { 
    block, 
    name, 
    state: { 
     checked: state, 
    } 
    }; 
}); 

减速立案CheckBox组件:

import {handleActions} from 'redux-actions'; 

import {CHANGE_CHECKBOX_STATE} from './CheckBox.actions'; 

export const checkBoxComponent = handleActions({ 
    CHANGE_CHECKBOX_STATE: (state, action) => ({ 
    [action.payload.block]: { 
     [action.payload.name]: action.payload.state 
    } 
    }) 
}, {}); 

我用block指定的页面,name指定特定组件的名称(例如性别),并以新状态作为对象。

但这种方法也存在一些问题:

  • 不能指定每个组件的初始状态,因为状态的键是动态的。
  • 使很多嵌套状态的商店结构复杂化。
  • 按组件聚集数据而不按形式聚合,这会使调试复杂化,并且在逻辑上不正确。

我没有足够的Redux和React经验来想出更好的解决方案来解决这个问题。但在我看来,我失去了大约阵营,Redux的关系,一些重要的东西,这提出了一些问题:

  • 这是个好主意来存储这些可重用的组件的状态进入终极版商店吗?

  • 我错误的将React组件与Redux动作和缩减器绑定在一起吗?

+0

我不明白为什么你需要存储控件的状态是这样的?是不是由实际数据支持?这些数据并没有给出它如何呈现的胡扯吗? 看起来像膨胀对我。 –

+0

@ChrisMartin我在这里试图解释我是如何到达这个决定的,但我也说过,我知道我做错了什么,我只是看不到它是什么。你能向我解释你将如何设计它?也许这样我会看到我的方法有什么问题。感谢您的回应! – Roc

+0

请观看以下视频:[https://egghead.io/series/getting-started-with-redux](https://egghead.io/series/getting-started-with-redux)... – Mike

这里最根本的错误是你有0个哑组件。像复选框这样的基本控件应该是仅使用道具的哑组件,他们的父母有责任选择和更新特定复选框的适当状态。

+0

Nono ,它们都是愚蠢的组件,动作和缩减器仅供父组件和商店使用。 – Roc

不要根据使用该状态的组件描述Redux Reducer(您的整体应用程序状态)。用另一种方式跟踪它,以描述性的方式描述你的应用程序状态,然后让你的“愚蠢的”组件消耗描述性状态。

而不是跟踪“与foo相关的表单的此复选框的状态”,跟踪“此foo的布尔值”,然后让复选框消耗该状态。

一个例子商店的复选框:

const initialState = { 
    someFooItem: { isCertainType: false } 
}; 

export function foos(state = initialState, action) { 
    switch(action.type){ 
     case(UPDATE_FOO_VALUE): 
      return { 
       ...state, 
       [action.payload.id]: { 
        isCertainType: action.payload.isCertainType 
       } 
      } 
    } 
} 

一个例子复选框消耗店

class CheckBox extends React.Component { 
    render() { 
     return <input type="checkbox" checked={this.props.checked} /> 
    } 
} 

父组件

class ParentComponent extends React.Component { 
    render() { 
     return <CheckBox checked={this.foo.isCertainType} /> 
    } 
} 
+0

如果我正确理解你,你的解决方案完全不能解决我的问题,因为你概括了复选框的形式,但是如果我有三个复选框,每个复选框都有不同的兴趣(例如体育,冒险,烹饪)其中我需要创建一个不同的减速器,甚至认为功能是一样的。 – Roc

+1

运动,冒险,烹饪将是“兴趣”,所以你可以有一个像'{兴趣:{烹饪:真实的,运动:假的,冒险:假的}}'的减速器,并用它来表示视图。 – Danita