Как использовать редуктор для нескольких действий в Redux? - PullRequest
1 голос
/ 02 июля 2019

Я недавно использую Redux и пытаюсь интегрировать React с Redux.Я хочу, чтобы все мои действия были в одном редукторе.На самом деле мой редуктор выглядит так:

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
    }
}

Проблема в том, что я вызываю действие, соответствующее типу GET_ALL_CONNECTIONS:

export const getAllConnections = () => {
    return async (dispatch) =>{
        const response = await Conexiones.get('/db/myConnections');
        dispatch({type: GET_ALL_CONNECTIONS, payload: response.data});
    }
}

Когда я вызываю эту функцию в компоненте React, предполагаетсяполучить несколько соединений от API и сохранить массив объектов, полученных в результате вызова API, в состоянии.Проблема в том, когда я хочу сохранить массив соединений в этом состоянии, чтобы затем отобразить это состояние и сгенерировать 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
    });

И компонент, где я выполняю вызов, выглядиткак это:

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);

Когда я делаю это с отдельным редуктором, называемым getAllConnections, и заменяю conexiones: ConnectionsReducers на conexiones: getAllConnections, это работает.Редуктор getAllConnections выглядит следующим образом:

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

    case 'GET_ALL_CONNECTIONS':
        return payload

    default:
        return state
    }
}

Я хочу знать, как выполнить эту работу, когда один редуктор получает все мои действия вместо отдельного редуктора для каждого действия.

Ответы [ 3 ]

1 голос
/ 02 июля 2019

Эта проблема связана с тем, что вы, вероятно, возвращаете различные структуры из вашего редуктора.Похоже, что редуктор предназначен для обработки объектов как состояния, но в этом случае вы возвращаете массив.Объекты не имеют функции карты.Вам нужно определить структуру вашего состояния для этого редуктора и придерживаться его, вы не можете переходить от массива к объекту и обратно, это недетерминированное поведение, для которого не создан редукс.

Я не знаюдетали реализации ваших 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
      }
  }

Следующий код должен получать состояния в виде массивов и возвращать обновленные состояния в виде массивов.

0 голосов
/ 03 июля 2019

Я решил эту проблему, заключив conexion:state.conexion в метод mapStateToProps с Object.values() следующим образом:

conexion: Object.values(state.conexion)
0 голосов
/ 02 июля 2019

Вы должны установить начальное состояние ... сейчас ваше состояние - пустой объект

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...