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

Я использую избыточную форму и что я делаю здесь, когда пользователь выбирает категорию, следующее поле выбора должно иметь все подкатегории в зависимости от выбранной категории.

Что я сделал, я создал API для выборки всех категорий, яинициировать действие через componentWillMount и загрузить все категории в поле выбора первых категорий, затем я использую formValueSelector из избыточной формы, чтобы получить выбранную категорию в состояние / this.props, затем я использую componentWillReceiveProps (), чтобы инициировать выборку подкатегорий с таким, например, «this».props.categoryId ", который я помещаю в состояние с formValueSelector, и это работает.

и мой вопрос: это правильный aporoach, есть ли лучший способ?и второй вопрос, как я могу сбросить поле categoryChildId, скажем, пустое, когда поле categoryId изменяется?

import React from 'react';
import moment from 'moment';
import { Field, reduxForm, formValueSelector } from 'redux-form';
import { connect } from 'react-redux';
import { Link, NavLink } from 'react-router-dom';
import {CopyToClipboard} from 'react-copy-to-clipboard';
import * as actions from '../../actions/category';

const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <div>
    <input {...input} placeholder={label} type={type} />
    {touched &&
     error &&
     <div className="error">{error}</div>}
  </div>
)

const renderTextArea = ({ input, label, type, meta: { touched, error } }) => (
  <div>
    <textarea {...input} placeholder={label} type={type} />
    {touched &&
     error &&
     <div className="error">{error}</div>}
  </div>
)

class AddProduct extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: `${process.env.SITE_URL}/user/${props.user.username}`,
      copied: false,
      isLoading: false
    };
  }

  componentWillMount() {
     this.props.startSetCategories()
  }

  componentWillReceiveProps(nextProps) {
      this.props.startSetCategoryChildren(nextProps.categoryId)
      console.log(nextProps)
  }

  renderCategorySelector = ({ input, meta: { touched, error } }) => {
    return (
      <div>
        <select {...input}>
          <option value="">select category</option>
          {!this.props.categories ? (
            <option value="">loading...</option>
          ) : (
            this.props.categories.map(category => <option value={category._id} key={category._id}>{category.name}</option>)
          )
        }
        </select>
        {touched && error && <span>{error}</span>}
      </div>
    )
  }

  renderCategoryChildSelector = ({ input, meta: { touched, error } }) => {
    return (
      <div>
        <select {...input}>
          <option value="">select sub category</option>
          {!this.props.categoryChildren ? (
            <option value="">loading...</option>
          ) : (
            this.props.categoryChildren.categoryChildren.map(categoryChild => <option value={categoryChild._id} key={categoryChild._id}>{categoryChild.name}</option>)
          )
          }
        </select>
        {touched && error && <span>{error}</span>}
      </div>
    )
  }

  submitForm = values => {
    console.log(values)

  }

  render() {
    const username = localStorage.getItem('username');
    const { user } = this.props;
    const { handleSubmit, pristine, submitting, categoryId } = this.props;

    return (
      <div className="profile-wrapper">
        <div className="profile">
          <form className="profile-addproduct-left" onSubmit={handleSubmit(this.submitForm.bind(this))}>
            <div className="profile-addproduct-title">
              <h2>New Product</h2>
              <p>Fill out the form.</p>
            </div>
            <div className="profile-form-group">
              <div className="profile-form-item">
                <p>Title</p>
                <Field
                  name="title"
                  type="text"
                  label="title of a product"
                  component={renderField}
                />
              </div>
              <div className="profile-form-item">
                <p>Category</p>
                <Field
                  name="categoryId"
                  type="text"
                  component={this.renderCategorySelector}
                  label="category"
                />
                {this.props.categoryId ?
                  <Field
                    name="categoryChildId"
                    type="text"
                    component={this.renderCategoryChildSelector}
                    label="categoryChild"
                  /> :
                  ''
                }
              </div>


              <div className="profile-form-item">
                <p>Description</p>
                <Field
                  name="description"
                  type="text"
                  label="Write some interesting..."
                  component={renderTextArea}
                />
              </div>


            </div>
            <div className="profile-addproduct-form-submit">
              <button className="button button--register" type="submit" disabled={this.state.isLoading || pristine}>Submit New Product</button>
            </div>
          </form>


        </div>
      </div>
    )
  }
};


AddProduct =  reduxForm({
  form: 'addproduct-form'
})(AddProduct)

const selector = formValueSelector('addproduct-form')

AddProduct = connect(state => {
  const categoryId = selector(state, 'categoryId')
  return {
    categoryId,
    categories: state.category.categories,
    categoryChildren: state.category.categoryChildren
  }
}, actions)(AddProduct)

export default AddProduct

1 Ответ

0 голосов
/ 05 мая 2018

Вы не должны вызывать startSetCategoryChildren (или любой другой API) в componentWillReceiveProps ... потому что он будет вызываться каждый раз, когда componentWillReceiveProps вызывает

componentWillReceiveProps(nextProps) {
  this.props.startSetCategoryChildren(nextProps.categoryId)
  console.log(nextProps)
}

Вместо этого вы можете сделать этона handleChange из Field

            <Field
              name="categoryId"
              type="text"
              component={this.renderCategorySelector}
              label="category"
              onChange={(e) => this.props.startSetCategoryChildren(e.target.value)}
            />
...