Я хочу собрать некоторые данные из формы на одном компоненте и показать его на другом - PullRequest
0 голосов
/ 23 сентября 2018

Я пытаюсь собрать некоторые подробности о компоненте и показать его на другом компоненте в двух словах.Но я не знаю, что плохого в том, что он собирает данные, но не будет отображаться в следующем компонентном хранилище резервов, действия уменьшают все, что создается.Может кто-нибудь сказать мне, что я делаю неправильно или чего-то не хватает?Спасибо

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

ShowDetails.js

import React, {Component} from 'react';
import {connect} from 'react-redux';

class ShowDetails extends Component{
     diplayDetails(details, index){
        return (
         <tr key={index}>
               <td>{details.name}</td>
               <td>{details.price}</td>
               <td>{details.company}</td>
               <td>{details.price}</td>
               <td>{details.expiry}</td>
                <td>{details.manufacture}</td>
           </tr>
         )

}
render(){
    return(
        <div className="container2">
            <h1> Show Details </h1>

            <table className="table">
                <thead className="thead-light">
                <tr>
                    <th scope="col">Name</th>
                    <th scope="col">Price</th>
                    <th scope="col">Company</th>
                    <th scope="col">Type</th>
                    <th scope="col">Expiry</th>
                    <th scope="col">Handle</th>

                </tr>
                </thead>
                <tbody>
                {this.props.detail.map(this.diplayDetails)}
                </tbody>
            </table>
        </div>
    );
}
}





 function mapStateToProps(state) {
    return{
        detail: state.detail
     };

 }

 export default connect (mapStateToProps) (ShowDetails);

Reducers.js

export default function productReducer(state=[], action) {
    switch (action.type) {
        case 'ADD_PRODUCT':
            return[...state,
                Object.assign({}, action.details)

            ];
        default:
            return state;
     }
 }

index.js для rootreducers

 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 }

  }

1 Ответ

0 голосов
/ 24 сентября 2018

Хорошо, много твиков, но подведем итог:

  • Все this.setState() вызовы должны выполняться в методе класса.
  • connect() требует 2 параметра: mapStateToProps и mapDispatchToProps ... если не используется mapStateToProps, вы должны передать null в качестве первого параметра.
  • Ваши имена для ввода формы были повсюду.Будьте последовательны: <input name="name" value={this.state.name} onChange={this.handleChange} />.Использование ввода id s не требуется и не рекомендуется.В этом случае this.handleChange использует e.target.name и e.target.value для отслеживания входных данных и их значений.
  • Убедитесь, что все входные данные были заполнены, прежде чем разрешить пользователю отправлять.
  • Избегайте использования жирных стрелок в методе рендеринга, например: onChange={ (e) => this.handleChange(e) }, потому что они будут дублироваться при каждом повторном рендеринге компонента.Иногда их нельзя избежать, но они направлены на минимизацию использования.
  • Проверьте крайние случаи (например, когда details пусто), в противном случае ваше приложение будет аварийно завершать работу при попытке map неопределенного или пустого объекта.
  • Действия должны возвращать payload (стандартное соглашение об именах).

Рабочий пример: https://codesandbox.io/s/qqlyqwnm3j

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

Containers / ShowDetails.js

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

Редукторы / index.js

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

actions / index.js

import { ADD_PRODUCT } from "../types";

export const submitDetails = payload => ({
  type: ADD_PRODUCT,
  payload
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...