如何在Redux中将reducer用于多个操作?

时间:2019-07-01 21:08:09

标签: javascript reactjs redux

我是Redux的新手,我正在尝试将React与Redux集成。我想要的是将所有动作都放在一个减速器中。其实我的减速器是这样的:

Pycharm windows 10

问题是当我调用与GET_ALL_CONNECTIONS类型相对应的动作时:

import {GET_ALL_CONNECTIONS, DELETE_CONNECTION, POST_CONNECTION} from '../actions';

const initialState = {

}

export default (state = initialState, { type, payload }) => {
    switch (type) {

    case GET_ALL_CONNECTIONS:
        return payload

    case POST_CONNECTION:
        return {...state, ...payload}

    case DELETE_CONNECTION:
        return {...state, ...payload}

    default:
        return state
    }
}

当我在React组件中调用此函数时,应该从API获得多个连接,并将API调用产生的对象数组保存为状态。 问题是,当我想将连接数组保存为该状态时,以后再映射该状态并使用export const getAllConnections = () => { return async (dispatch) =>{ const response = await Conexiones.get('/db/myConnections'); dispatch({type: GET_ALL_CONNECTIONS, payload: response.data}); } } 元素中的每个连接生成options时。当我渲染组件时,它将引发下一个错误:

select

将所有减速器组合在一起的文件如下所示:

TypeError: this.props.conexiones.map is not a function

我打电话的组件看起来像这样:

import {combineReducers} from 'redux';
import {reducer as formReducer } from 'redux-form';

    import postUser from './postUser';
    import postConnection from './postConnection';
    import getAllConnections from './getAllConnections';
    import ConnectionsReducer from './ConnectionsReducer';

    export default combineReducers({
        newUser: postUser,
        form: formReducer,
        conexiones: ConnectionsReducer
    });

当我使用名为getAllConnections的单独的reducer并将import React, { Component } from 'react'; import { Grid, Container, Select, Button, withStyles, FormControl, InputLabel, MenuItem } from '@material-ui/core'; import {connect} from 'react-redux'; import {reduxForm, Field} from 'redux-form'; import {deleteConnection, getAllConnections} from '../actions'; const styles = theme => ({ root: { display: 'flex', flexWrap: 'wrap', }, formControl: { margin: theme.spacing(1), minWidth: 120, }, selectEmpty: { marginTop: theme.spacing(2), }, }); class BorrarConexion extends Component { componentDidMount() { this.props.getAllConnections(); } handleSubmit = ({conexionId}) => { this.props.deleteConnection(conexionId); } renderConexiones = () => { return this.props.conexiones.map(conexion =>{ return (<MenuItem key={conexion.id} value={conexion.id}>{conexion.connectionUrl}</MenuItem>); }); } renderSelectField = ({input,label,meta: { touched, error },children,...custom}) =>{ return ( <FormControl> <InputLabel>Seleccione la URL que desea eliminar</InputLabel> <Select {...input} {...custom}> {this.renderConexiones()} </Select> </FormControl> ) } render() { return ( <Container> <Grid container direction="column"> <Field name="conexionId" component={this.renderSelectField} label="Favorite Color"/> <Button onClick={this.props.handleSubmit(this.handleSubmit)}>Eliminar</Button> </Grid> </Container> ); } } const mapStateToProps = (state) => { return {conexiones: state.conexiones} } const BorraConexionEstilizado = withStyles(styles)(BorrarConexion); const formWrapped = reduxForm({form: 'delete_connection'})(BorraConexionEstilizado); export default connect(mapStateToProps, {getAllConnections, deleteConnection})(formWrapped); 替换为conexiones: ConnectionsReducers时,它可以工作。 getAllConnections减速器如下所示:

conexiones: getAllConnections

我想知道如何使用一个减速器接收我的所有动作而不是每个动作使用一个单独的减速器来完成这项工作。

3 个答案:

答案 0 :(得分:1)

此问题与以下事实有关:您可能会从减速器返回不同的结构。看起来reducer打算将对象作为状态来处理,但在这种情况下,您将返回一个数组。对象没有地图功能。您需要确定此reducer的状态结构并坚持下去,不能从数组更改为对象再返回,这是不确定性的行为,并非为redux构建。

我不知道您的API的实现细节,但这是需要更新的主要领域

  const initialState = []

  export default (state = initialState, { type, payload }) => {
      switch (type) {

      case GET_ALL_CONNECTIONS:
          return payload //hoping that your api gave an array here

      case POST_CONNECTION:
          //return {...state, ...payload} //this is clearly returning an object
          return [...state, payload] //now it returns an array with a new item

      case DELETE_CONNECTION:
          //return {...state, ...payload} //this is clearly returning an object
          return state.filter(item => item.id !== payload.id) //now it returns a filtered array

      default:
          return state
      }
  }

以下代码应将状态作为数组接收,并将更新后的状态作为数组返回。

答案 1 :(得分:0)

您必须设置初始状态...现在,您的状态是一个空对象

答案 2 :(得分:0)

我通过将conexion:state.conexion的{​​{1}}用mapStateToProps包围起来来解决了这个问题,

Object.values()