Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为React可重用组件设计Redux操作和缩减器_Javascript_Reactjs_Redux - Fatal编程技术网

Javascript 为React可重用组件设计Redux操作和缩减器

Javascript 为React可重用组件设计Redux操作和缩减器,javascript,reactjs,redux,Javascript,Reactjs,Redux,我正在用Redux和React开发一个大型应用程序,我决定制作一些可重用的组件,如自定义复选框和单选按钮 由于我希望将这些信息存储到Redux存储中,以便能够轻松调试应用程序的状态,并且同一组件在任何地方都具有相同的功能,因此为每个组件创建还原器和操作似乎是一个好主意 但是,Redux reducer返回一个新状态并将其保存在存储中,并将reducer的名称作为键,这禁止使用相同的操作和reducer在同一页面中使用多个相同类型的组件,但保持不同的状态 我认为有两种方法可以解决这个问题: 为我

我正在用Redux和React开发一个大型应用程序,我决定制作一些可重用的组件,如自定义复选框和单选按钮

由于我希望将这些信息存储到Redux存储中,以便能够轻松调试应用程序的状态,并且同一组件在任何地方都具有相同的功能,因此为每个组件创建还原器和操作似乎是一个好主意

但是,Redux reducer返回一个新状态并将其保存在存储中,并将reducer的名称作为键,这禁止使用相同的操作和reducer在同一页面中使用多个相同类型的组件,但保持不同的状态

我认为有两种方法可以解决这个问题:

  • 为我使用的每个组件创建不同的操作和简化程序,即使组件及其功能是相同的。这个解决方案似乎不是一个好的解决方案,因为会有很多冗余代码

  • 创建具有足够参数的操作,以便能够区分减速器中的每个操作,从而仅更改指定状态的一部分

我提出了第二个选择

复选框组件的操作文件:

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,
    }
  };
});
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
    }
  })
}, {});
复选框组件的减速器文件:

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,
    }
  };
});
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关系的一些重要方面,这引发了一些问题:

  • 将此可重用组件的状态存储到Redux存储中是一个好主意吗

  • 我用Redux操作和reducer将React组件绑定在一起是错误的吗


    • 这里的根本错误是您没有哑组件。复选框之类的基本控件应该是只使用道具的哑组件,它们的父控件有责任为特定复选框选择并更新适当的状态。

      不要用使用该状态的组件来描述Redux还原器(您的整个应用程序状态)。以另一种方式跟踪它,以描述性的方式描述应用程序状态,然后让“哑”组件使用该描述性状态

      与其跟踪“与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复选框扩展了React.Component{
      render(){
      返回
      }
      }
      
      父组件

      class ParentComponent extends React.Component {
           render() {
               return <CheckBox checked={this.foo.isCertainType} />
           }
      }
      
      类ParentComponent扩展了React.Component{ render(){ 返回 } }
      Nono,它们都是哑组件,操作和减缩器只供父组件和存储使用。我不明白为什么需要像这样存储控件的状态?没有实际数据支持吗?而且这些数据对它的呈现方式没有任何影响?“对我来说似乎有点夸张。”克里斯马汀我试图在这里解释我是如何做出这个决定的,但我也说我知道我做错了什么,我只是不明白这是什么。你能向我解释一下你将如何设计它吗?也许那样我会发现我的方法有什么问题。感谢您的回复!请观看以下视频:……如果我正确理解您,您的解决方案并不能完全解决我的问题,因为您概括了复选框的形式,但如果我有三个复选框,每个复选框都有不同的兴趣(例如,运动、冒险、烹饪)对于其中的每一个,我都需要创建一个不同的减速机,即使功能是相同的。运动、冒险、烹饪都是“兴趣”,因此您可以有一个减速机,如
      {interests:{Cooking:true,Sports:false,advention:false}
      ,并使用它来表示视图。