Reactjs 我想从一个组件上的表单中收集一些数据,然后在另一个组件上显示

Reactjs 我想从一个组件上的表单中收集一些数据,然后在另一个组件上显示,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

我试图收集一些有关组件的详细信息,并在简短的2页的另一个组件上显示它。但我不知道怎么了,它收集了数据,但不会在下一个组件redux存储中显示,操作减少了创建的所有内容。有人能告诉我我做错了什么或者我遗漏了什么吗? 多谢各位

GetDetail.js

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
    作为第一个参数
  • 你的表单输入名称到处都是。保持一致:
    。不需要也不建议使用输入
    id
    s。在这种情况下,
    this.handleChange
    利用
    e.target.name
    e.target.value
    跟踪输入及其值
  • 在允许用户提交之前,确保已填写所有输入
  • 避免在render方法中使用胖箭头函数,例如:
    onChange={(e)=>this.handleChange(e)}
    ,因为它们在每个组件重新渲染期间都会重复。有时它们是无法避免的,但目的是尽量减少使用
  • 检查边缘情况(例如当
    详细信息
    为空时),否则,您的应用程序将在尝试映射未定义或空对象时崩溃
  • 操作应返回一个
    有效负载
    (标准命名约定)
工作示例:

容器/ProductForm.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
});
操作/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}
5
this.handleSubmit
应该是
handleSubmit(e){e.preventDefault();this.props.SubmitDetails(this.state.details);}
--
e.preventDefault()
防止在提交时刷新页面。我发现了一些问题。创建一个沙箱,给我几分钟。谢谢你,这真的帮了我很多忙,帮了我很多忙!:)