从react-redux向后端API发送请求



我的后端服务器是NodeJs连接到MongoDB地图集,有一个名为companyorders的路由它接受post请求,使用户能够创建公司订单。我试图通过Redux从react应用程序发送post请求。

这是我的代码…

<<p>回来的商店/strong>
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
<<p>回来的行动/strong>
import axios from 'axios';
import { GET_ERRORS, ADD_COMPANY_ORDER } from './types';
// Add Company Order
export const addCompanyOrder = (orderData) => (dispatch) => {
axios
.post('/api/companyorder/create', orderData)
.then((res) =>
dispatch({
type: ADD_COMPANY_ORDER,
payload: res.data,
})
)
.catch((err) =>
dispatch({
type: GET_ERRORS,
payload: err.response.data,
})
);
};

回来的还原剂

import { ADD_COMPANY_ORDER } from '../actions/types';
const initialState = {};
export default function addCompanyOrder(state = initialState, action) {
switch (action.type) {
case ADD_COMPANY_ORDER:
return {
...state,
initialState: action.payload,
};
default:
return state;
}
}

Redux组合式减速器

import { combineReducers } from 'redux';
import addCompanyOrder from './companyOrderReducer';
export default combineReducers({
co_order: addCompanyOrder,
});

react组件

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { addCompanyOrder } from '../../actions/companyOrderActions';
class Companyorder extends Component {
constructor(props) {
super(props);
this.state = {
orderName: '',
date: '',
orderQuantity: '',
orderSupplier: '',
orderCost: '',
oderTax: '',
supplierInfo: [
{
name: '',
location: '',
phone: '',
email: '',
},
],
oderReceived: '',
errors: {},
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
componentDidUpdate(nextProps) {
if (nextProps.errors) {
this.setState({ errors: nextProps.errors });
}
}
onSubmit(e) {
e.preventDefault();
const newOrder = {
orderName: this.state.orderName,
date: this.state.date,
orderQuantity: this.state.orderQuantity,
orderSupplier: this.state.orderSupplier,
orderCost: this.state.orderCost,
oderTax: this.state.oderTax,
name: this.state.name,
location: this.state.location,
phone: this.state.phone,
email: this.state.email,
};
this.props.addCompanyOrder(newOrder);
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
render() {
const { errors } = this.state;
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<Link to="/" className="btn btn-link">
<i className="fas fa-arrow-circle-left" /> Back To Dashboard
</Link>
</div>
</div>
<div className="card">
<div className="card-header"> Company Order Form</div>
<div className="card-body">
<div className="form-group row">
<label htmlFor="orderName" className="col-2 col-form-label">
Order Name
</label>
<div className="col-10">
<input
className="form-control"
type="text"
name="orderName"
minLength="2"
required
onChange={this.onChange}
value={this.state.orderName}
error={errors.orderName}
/>
</div>
</div>
<div className="form-group row">
<label htmlFor="date" className="col-2 col-form-label">
Order Date
</label>
<div className="col-10">
<input
className="form-control"
type="date"
name="date"
minLength="2"
required
onChange={this.onChange}
value={this.state.date}
error={errors.date}
/>
</div>
</div>
<div className="form-group row">
<label htmlFor="orderQuantity" className="col-2 col-form-label">
Order Quantity
</label>
<div className="col-10">
<input
className="form-control"
type="number"
name="orderQuantity"
minLength="2"
required
onChange={this.onChange}
value={this.state.orderQuantity}
error={errors.orderQuantity}
/>
</div>
</div>
<div className="form-group row">
<label htmlFor="orderSupplier" className="col-2 col-form-label">
Order Supplier
</label>
<div className="col-10">
<input
className="form-control"
type="text"
name="orderSupplier"
minLength="2"
required
onChange={this.onChange}
value={this.state.orderSupplier}
error={errors.orderSupplier}
/>
</div>
</div>
<div className="form-group row">
<label htmlFor="orderCost" className="col-2 col-form-label">
Order Cost
</label>
<div className="col-10">
<input
className="form-control"
type="text"
name="orderCost"
minLength="2"
required
onChange={this.onChange}
value={this.state.orderCost}
error={errors.orderCost}
/>
</div>
</div>
<div className="form-group row">
<label htmlFor="oderTax" className="col-2 col-form-label">
Order Tax
</label>
<div className="col-10">
<input
className="form-control"
type="text"
name="oderTax"
minLength="2"
required
onChange={this.onChange}
value={this.state.oderTax}
error={errors.orderTax}
/>
</div>
</div>
<div className="card-header">
<h5>Supplier info</h5>
<div className="card-body">
<div className="form-group row">
<label htmlFor="name" className="col-2 col-form-label">
Name
</label>
<div className="col-10">
<input
className="form-control"
type="text"
name="name"
minLength="2"
required
onChange={this.onChange}
value={this.state.name}
error={errors.name}
/>
</div>
</div>
<div className="form-group row">
<label htmlFor="location" className="col-2 col-form-label">
Location
</label>
<div className="col-10">
<input
className="form-control"
type="text"
name="location"
minLength="2"
required
onChange={this.onChange}
value={this.state.location}
error={errors.loaction}
/>
</div>
</div>
<div className="form-group row">
<label htmlFor="phone" className="col-2 col-form-label">
Phone
</label>
<div className="col-10">
<input
className="form-control"
type="text"
name="phone"
minLength="2"
required
onChange={this.onChange}
value={this.state.phone}
error={errors.phone}
/>
</div>
</div>
<div className="form-group row">
<label htmlFor="email" className="col-2 col-form-label">
Email
</label>
<div className="col-10">
<input
className="form-control"
type="text"
name="email"
minLength="2"
required
onChange={this.onChange}
value={this.state.email}
error={errors.email}
/>
</div>
</div>
</div>
</div>
<input
type="submit"
value="Submit"
className="btn btn-primary btn-block"
/>
</div>
</div>
</div>
);
}
}
Companyorder.propTypes = {
addCompanyOrder: PropTypes.func.isRequired,
co_order: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired,
};
const mapStateToProps = (state) => ({
co_order: state.co_order,
errors: state.errors,
});
export default connect(mapStateToProps, { addCompanyOrder })(
withRouter(Companyorder)
);

代码编译成功,但是redux没有发出任何请求,甚至没有填充redux状态。如果知道错误或更好的方法,请留下您的回复,我非常感激。

似乎您没有在代码的任何地方调用您的onSubmit处理程序。你应该用form标签包装你的表单,并设置onSubmit道具到你的处理器函数。

<form onSubmit={this.onSubmit}>
...
</form>

顺便说一下,你的减速器好像不对。在我看来,您可能需要更类似于此的内容:

import { ADD_COMPANY_ORDER } from '../actions/types';
const initialState = {
co_orders: []
};
export default function addCompanyOrder(state = initialState, action) {
switch (action.type) {
case ADD_COMPANY_ORDER:
const newCoOrder = action.payload;
return {
co_orders: [...state.co_orders, newCoOrder];
};
default:
return state;
}
}

如果你的应用程序增加了复杂性,其他不相关的提示:

  • 考虑使用某种不可变性库,如Immer或ImmutableJS(我会选择第一个)。裁判:https://redux.js.org/recipes/using-immutablejs-with-redux/using-immutablejs-with-redux
  • 考虑编写选择器来从redux状态中获取数据,也许可以使用reselect库。裁判:https://redux.js.org/recipes/computing-derived-data/
  • 如果你的应用程序中有很多表单,可以考虑使用表单库,它会让你的工作更轻松(Formik, react-final-form或react-hook-form等)