Javascript 如何在Redux中为多个操作使用减速机?
我是使用Redux的新手,我正在尝试将React与Redux集成。我想要的是把我所有的行动都放在一个减速器里。实际上我的减速机是这样的:Javascript 如何在Redux中为多个操作使用减速机?,javascript,reactjs,redux,Javascript,Reactjs,Redux,我是使用Redux的新手,我正在尝试将React与Redux集成。我想要的是把我所有的行动都放在一个减速器里。实际上我的减速机是这样的: import {GET_ALL_CONNECTIONS, DELETE_CONNECTION, POST_CONNECTION} from '../actions'; const initialState = { } export default (state = initialState, { type, payload }) => {
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
}
}
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);
export default (state = [], { type, payload }) => {
switch (type) {
case 'GET_ALL_CONNECTIONS':
return payload
default:
return state
}
}
conexion: Object.values(state.conexion)
问题是,当我调用与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调用的对象结果数组保存在状态中。
问题是,当我想将connections数组保存在状态中,以便以后映射该状态,并使用select元素中的每个连接生成选项。渲染组件时,它会抛出下一个错误:
TypeError: this.props.conexiones.map is not a function
我合并所有还原器的文件如下所示:
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
}
}
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);
export default (state = [], { type, payload }) => {
switch (type) {
case 'GET_ALL_CONNECTIONS':
return payload
default:
return state
}
}
conexion: Object.values(state.conexion)
我调用的组件如下所示:
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
}
}
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);
export default (state = [], { type, payload }) => {
switch (type) {
case 'GET_ALL_CONNECTIONS':
return payload
default:
return state
}
}
conexion: Object.values(state.conexion)
我想知道如何在一个减速机接收我的所有操作而不是每个操作的单个减速机的情况下执行此操作。您必须设置初始状态。。。现在,您的状态是一个空对象此问题与您可能从减速器返回不同结构的事实有关。看起来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
}
}
以下代码应将状态接收为数组,并将更新后的状态返回为数组。我通过在MapStateTrops方法中使用Object.Value包围conexion:state.conexion解决了此问题,如下所示:
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
}
}
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);
export default (state = [], { type, payload }) => {
switch (type) {
case 'GET_ALL_CONNECTIONS':
return payload
default:
return state
}
}
conexion: Object.values(state.conexion)
我用什么来初始化它?还有空数组?或者调用函数以获取所有连接?空数组。您应该以数据类型一致的方式设计减缩器。但是减缩器返回的是一个数组。为什么getAllConnections reducer可以工作,但ConnectionsReducer不能工作?我不理解你的评论,请提出任何后续问题。我不能100%准确地回答你的问题,如果不知道API的详细信息,尽管我已经更新了代码,仍然显示地图错误。我注意到的是,如果我在getAllConnections操作中放置一个控制台日志,打印response.data,它将连接打印为数组,如果我在Borraconexiones componentDidMount方法上控制台日志props.conexions,在调用函数getAllConnections后,它将打印一个没有元素的数组,是在我打开选择器之后,当props.conexiones打印带有连接的数组时。你认为这就是错误发生的原因吗?所有这些都使用conexiones:getAllConnections作为reducer。您应该诚实地在renderconexions中记录该值,并查看该值是什么,获取后立即登录将始终提供一个空数组,因为您没有等待承诺解决我将其记录在那里,它将返回一个对象数组如果这是真正的解决方案,那么您的Conexiones就有问题。获取&39/db/myConnections&39;函数,它可能返回一个对象,而不是预期的数组。您的解决方案更像是一种转换对象的黑客&39;将值添加到数组中