Reactjs 我想从一个组件上的表单中收集一些数据,然后在另一个组件上显示
我试图收集一些有关组件的详细信息,并在简短的2页的另一个组件上显示它。但我不知道怎么了,它收集了数据,但不会在下一个组件redux存储中显示,操作减少了创建的所有内容。有人能告诉我我做错了什么或者我遗漏了什么吗? 多谢各位 GetDetail.jsReactjs 我想从一个组件上的表单中收集一些数据,然后在另一个组件上显示,reactjs,react-redux,react-router,Reactjs,React Redux,React Router,我试图收集一些有关组件的详细信息,并在简短的2页的另一个组件上显示它。但我不知道怎么了,它收集了数据,但不会在下一个组件redux存储中显示,操作减少了创建的所有内容。有人能告诉我我做错了什么或者我遗漏了什么吗? 多谢各位 GetDetail.js import React, {Component} from 'react'; import {connect} from 'react-redux'; import * as Actions from '../Actions/Action' cl
import React, {Component} from 'react';
import {connect} from 'react-redux';
import * as Actions from '../Actions/Action'
class GetDetails extends Component{
constructor(props, context){
super(props, context);
this.state={
details:{
name:"",
price:"",
company:"",
manufacture:"",
expiry:""
}
};
this.HandleSubmit = this.HandleSubmit.bind(this);
}
HandleSubmit() {
this.props.SubmitDetails(this.state.details);
}
render(){
return(
<div className="container" >
<form>
<h1>Enter Details Here</h1>
<div className="form-group">
<label>Name</label>
<input type="text" className="form-control" id="inputEmail4" placeholder="Email"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {name: e.target.value})})}
value={this.state.text}/>
</div>
<div className="form-group">
<label >Price</label>
<input type="text" className="form-control" id="inputAddress" placeholder="1234 Main St"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {price: e.target.value})})}
value={this.state.text}/>
</div>
<div className="form-group">
<label >Company</label>
<input type="text" className="form-control" id="inputAddress2"
placeholder="Apartment, studio, or floor"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {company: e.target.value})})}
value={this.state.text}/>
</div>
<div className="form-group">
<label >Type</label>
<select id="inputState" className="form-control">
<option selected>Choose...</option>
<option>New</option>
<option>Used</option>
</select>
</div>
<div className="form-group ">
<label >Expiry Date</label>
<input type="text" className="form-control" id="inputCity"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {manufacture: e.target.value})})}
value={this.state.text}/>
</div>
<div className="form-group ">
<label>Manufacture Date</label>
<input type="text" className="form-control" id="inputZip"
onChange={(e)=> this.setState({details: Object.assign(this.state.details, {expiry: e.target.value})})}
value={this.state.text}/>
</div>
<button type="submit" className="btn btn-primary" value="Save" onClick={this.HandleSubmit}>Submit</button>
</form>
</div>
);
}
}
function mapDispatchToProps(dispatch) {
return {
SubmitDetails: details => dispatch(Actions.SubmitDetails(details))
}
}
export default connect(mapDispatchToProps) (GetDetails);
rootreducer的index.js
import {combineReducers} from 'redux';
import ProductReducer from './Reducers';
const rootReducer = combineReducers({
detail: ProductReducer
});
export default root
Actions.js
export function SubmitDetails(details) {
return{ type: 'ADD_PRODUCT',details }
}
好的,有很多调整,但总结一下:
- 所有
调用都应该在类方法中进行this.setState()
需要两个参数:connect()
和MapStateTrops
。。。如果未使用mapDispatchToProps
,则必须传入MapStateTops
作为第一个参数null
- 你的表单输入名称到处都是。保持一致:
。不需要也不建议使用输入
s。在这种情况下,id
利用this.handleChange
和e.target.name
跟踪输入及其值e.target.value
- 在允许用户提交之前,确保已填写所有输入李>
- 避免在render方法中使用胖箭头函数,例如:
,因为它们在每个组件重新渲染期间都会重复。有时它们是无法避免的,但目的是尽量减少使用onChange={(e)=>this.handleChange(e)}
- 检查边缘情况(例如当
为空时),否则,您的应用程序将在尝试映射未定义或空对象时崩溃详细信息
- 操作应返回一个
(标准命名约定)李>有效负载
import React, { Component } from "react";
import { connect } from "react-redux";
import { submitDetails } from "../actions/";
import { browserHistory } from "react-router";
class ProductForm extends Component {
state = {
name: "",
price: "",
manufacturer: "",
condition: "",
manufactureDate: "",
expirationDate: ""
};
handleChange = e => this.setState({ [e.target.name]: e.target.value });
handleSubmit = e => {
e.preventDefault();
const {
name,
price,
manufacturer,
condition,
manufactureDate,
expirationDate
} = this.state;
if (
!name ||
!price ||
!manufacturer ||
!condition ||
!manufactureDate ||
!expirationDate
)
return;
this.props.submitDetails({ ...this.state });
browserHistory.push("/details");
};
render = () => (
<div style={{ textAlign: "center" }} className="container">
<form
style={{ width: 400, margin: "0 auto" }}
onSubmit={this.handleSubmit}
>
<h1 style={{ textAlign: "center" }}>Enter Product Details</h1>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Name</label>
<input
type="text"
className="uk-input"
name="name"
placeholder="Name of product"
onChange={this.handleChange}
value={this.state.name}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Price</label>
<input
type="number"
className="uk-input"
name="price"
placeholder="Product price"
onChange={this.handleChange}
value={this.state.price}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Manufacturer</label>
<input
type="text"
className="uk-input"
name="manufacturer"
placeholder="Product manufacturer"
onChange={this.handleChange}
value={this.state.manufacturer}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Condition</label>
<select
name="condition"
className="uk-select"
value={this.state.condition}
onChange={this.handleChange}
>
<option>Choose...</option>
<option>New</option>
<option>Used</option>
</select>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group "
>
<label style={{ paddingLeft: 10 }}>Manufacture Date</label>
<input
type="date"
className="uk-input"
name="manufactureDate"
onChange={this.handleChange}
value={this.state.manufactureDate}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group "
>
<label style={{ paddingLeft: 10 }}>Expiration Date</label>
<input
type="date"
className="uk-input"
name="expirationDate"
onChange={this.handleChange}
value={this.state.text}
/>
</div>
<button type="submit" className="uk-button uk-button-primary">
Submit
</button>
</form>
</div>
);
}
export default connect(
null,
{ submitDetails }
)(ProductForm);
import map from "lodash/map";
import isEmpty from "lodash/isEmpty";
import React from "react";
import { connect } from "react-redux";
const ShowDetails = ({ details }) =>
isEmpty(details) ? (
<div style={{ textAlign: "center", marginTop: 20 }}>
<h3 style={{ color: "red" }}>No Products Found!</h3>
</div>
) : (
<div style={{ textAlign: "center" }}>
<h1>Product Details </h1>
<table style={{ marginBottom: 10 }} className="products">
<thead className="thead-light">
<tr>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Manufacturer</th>
<th scope="col">Condition</th>
<th scope="col">Manufacture Date</th>
<th scope="col">Expiration Date</th>
</tr>
</thead>
<tbody>
{map(
details,
(
{
name,
price,
manufacturer,
condition,
manufactureDate,
expirationDate
},
key
) => (
<tr key={key}>
<td>{name}</td>
<td>${price}</td>
<td>{manufacturer}</td>
<td>{condition}</td>
<td>{manufactureDate}</td>
<td>{expirationDate}</td>
</tr>
)
)}
</tbody>
</table>
</div>
);
export default connect(state => ({ details: state.product.details }))(
ShowDetails
);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { ADD_PRODUCT } from "../types";
const productReducer = (state = { details: [] }, { type, payload }) => {
switch (type) {
case ADD_PRODUCT:
return {
...state,
details: [...state.details, payload]
};
default:
return state;
}
};
export default combineReducers({
product: productReducer,
routing
});
import { ADD_PRODUCT } from "../types";
export const submitDetails = payload => ({
type: ADD_PRODUCT,
payload
});
操作/index.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { submitDetails } from "../actions/";
import { browserHistory } from "react-router";
class ProductForm extends Component {
state = {
name: "",
price: "",
manufacturer: "",
condition: "",
manufactureDate: "",
expirationDate: ""
};
handleChange = e => this.setState({ [e.target.name]: e.target.value });
handleSubmit = e => {
e.preventDefault();
const {
name,
price,
manufacturer,
condition,
manufactureDate,
expirationDate
} = this.state;
if (
!name ||
!price ||
!manufacturer ||
!condition ||
!manufactureDate ||
!expirationDate
)
return;
this.props.submitDetails({ ...this.state });
browserHistory.push("/details");
};
render = () => (
<div style={{ textAlign: "center" }} className="container">
<form
style={{ width: 400, margin: "0 auto" }}
onSubmit={this.handleSubmit}
>
<h1 style={{ textAlign: "center" }}>Enter Product Details</h1>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Name</label>
<input
type="text"
className="uk-input"
name="name"
placeholder="Name of product"
onChange={this.handleChange}
value={this.state.name}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Price</label>
<input
type="number"
className="uk-input"
name="price"
placeholder="Product price"
onChange={this.handleChange}
value={this.state.price}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Manufacturer</label>
<input
type="text"
className="uk-input"
name="manufacturer"
placeholder="Product manufacturer"
onChange={this.handleChange}
value={this.state.manufacturer}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group"
>
<label style={{ paddingLeft: 10 }}>Condition</label>
<select
name="condition"
className="uk-select"
value={this.state.condition}
onChange={this.handleChange}
>
<option>Choose...</option>
<option>New</option>
<option>Used</option>
</select>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group "
>
<label style={{ paddingLeft: 10 }}>Manufacture Date</label>
<input
type="date"
className="uk-input"
name="manufactureDate"
onChange={this.handleChange}
value={this.state.manufactureDate}
/>
</div>
<div
style={{ textAlign: "left", marginBottom: 20 }}
className="form-group "
>
<label style={{ paddingLeft: 10 }}>Expiration Date</label>
<input
type="date"
className="uk-input"
name="expirationDate"
onChange={this.handleChange}
value={this.state.text}
/>
</div>
<button type="submit" className="uk-button uk-button-primary">
Submit
</button>
</form>
</div>
);
}
export default connect(
null,
{ submitDetails }
)(ProductForm);
import map from "lodash/map";
import isEmpty from "lodash/isEmpty";
import React from "react";
import { connect } from "react-redux";
const ShowDetails = ({ details }) =>
isEmpty(details) ? (
<div style={{ textAlign: "center", marginTop: 20 }}>
<h3 style={{ color: "red" }}>No Products Found!</h3>
</div>
) : (
<div style={{ textAlign: "center" }}>
<h1>Product Details </h1>
<table style={{ marginBottom: 10 }} className="products">
<thead className="thead-light">
<tr>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Manufacturer</th>
<th scope="col">Condition</th>
<th scope="col">Manufacture Date</th>
<th scope="col">Expiration Date</th>
</tr>
</thead>
<tbody>
{map(
details,
(
{
name,
price,
manufacturer,
condition,
manufactureDate,
expirationDate
},
key
) => (
<tr key={key}>
<td>{name}</td>
<td>${price}</td>
<td>{manufacturer}</td>
<td>{condition}</td>
<td>{manufactureDate}</td>
<td>{expirationDate}</td>
</tr>
)
)}
</tbody>
</table>
</div>
);
export default connect(state => ({ details: state.product.details }))(
ShowDetails
);
import { routerReducer as routing } from "react-router-redux";
import { combineReducers } from "redux";
import { ADD_PRODUCT } from "../types";
const productReducer = (state = { details: [] }, { type, payload }) => {
switch (type) {
case ADD_PRODUCT:
return {
...state,
details: [...state.details, payload]
};
default:
return state;
}
};
export default combineReducers({
product: productReducer,
routing
});
import { ADD_PRODUCT } from "../types";
export const submitDetails = payload => ({
type: ADD_PRODUCT,
payload
});
如果您下次可以在代码沙盒中使用此选项,将非常有帮助:。其中一个潜在问题是,您正在从
“../Actions/action”
导入操作创建者,而文件名为action
,但我不确定这是否就是全部。您添加的带有一个组件的对象是否真的添加到了redux存储中?1。不要在渲染方法中使用setState()。。。创建类方法(就像您对this.handleSubmit
所做的那样)。2.您的
应该是
,提交按钮应该是:提交3。您的productReducer
的初始状态应该是一个对象{}
,然后case ADD\u PRODUCT:
应该返回{…状态,action.details}
4。showDetails.js
中的mapStateToProps
应该是返回{detail:state.detail.details}
5this.handleSubmit
应该是handleSubmit(e){e.preventDefault();this.props.SubmitDetails(this.state.details);}
--e.preventDefault()
防止在提交时刷新页面。我发现了一些问题。创建一个沙箱,给我几分钟。谢谢你,这真的帮了我很多忙,帮了我很多忙!:)