2017-02-03 2 views
1

Я пытаюсь создать повторно используемый компонент для создания простых форм, имеющих проверку и обработку действий отправки. Я могу использовать его сам, но когда я пытаюсь сделать функциональный компонент для инъекции реквизита, я застрял в этой ошибке.Попытка повторного использования редукционной формы с функциональным компонентом

enter image description here

Этот класс использует компонент для создания форм

import React from 'react'; 
 
import CustomReduxForm from './CustomReduxForm'; 
 

 
class LoginForm extends React.Component { 
 
    getFields() { 
 
    return [ 
 
     { 
 
     name : 'username', 
 
     type : 'text', 
 
     label : 'User', 
 
     mandatory : true 
 
     }, 
 
     { 
 
     name : 'password', 
 
     type : 'password', 
 
     label : 'Password', 
 
     mandatory : true 
 
     } 
 
    ]; 
 
    } 
 

 
    handleFormSubmit(values) { 
 
    console.log(values) 
 
    } 
 

 
    render() { 
 
    return (
 
     <div> 
 
     <div>Test</div> 
 
     <CustomReduxForm 
 
      formName="LoginForm" 
 
      fields={this.getFields()} 
 
      onSubmit={this.handleFormSubmit} 
 
     /> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
export default LoginForm;

Это компонент для построения форм

import React from 'react'; 
 
import { reduxForm, Field } from 'redux-form'; 
 

 
function CustomReduxForm(props) { 
 

 
    class CustomForm extends React.Component { 
 
    render() { 
 
     const { handleSubmit } = this.props; 
 
     return (
 
     <div style={{ margin: '30px' }}> 
 
      <form onSubmit={handleSubmit(props.onSubmit)}> 
 
      {fields.map(myField => renderFieldset(myField))} 
 
      <button className="btn btn-primary" type="submit">Submit</button> 
 
      </form> 
 
     </div> 
 
    ); 
 
    } 
 
    } 
 

 
    const renderInput = field => { 
 
    return (
 
     <div className={`form-group ${field.meta.touched && field.meta.invalid ? 'has-danger' : ''}`}> 
 
      <input 
 
      {...field.input} 
 
      type={field.type} 
 
      className="form-control" 
 
      /> 
 

 
      {field.meta.touched && field.meta.error && <div className="text-help">{field.meta.error}</div>} 
 
     </div> 
 
    ); 
 
    } 
 

 
    const renderFieldset = customField => { 
 
     return (
 
     <div> 
 
      <label htmlFor={customField.name}>{customField.label}</label> 
 
      <Field 
 
      name={customField.name} 
 
      component={renderInput} 
 
      type={customField.type} /> 
 
     </div> 
 
    ); 
 
    } 
 

 
    const validate = values => { 
 
    const errors = {} 
 

 
    props.fields.forEach((customField) => 
 
    { 
 
     if(customField.mandatory && ! values[customField.name]) { 
 
     errors[customField.name] = `You must enter a valid value for ${customField.label}!`; 
 
     } 
 
    }); 
 

 
    return errors 
 
    } 
 

 
    return reduxForm({ 
 
    form: props.formName, 
 
    validate 
 
    })(CustomForm); 
 

 
}; 
 

 
export default CustomReduxForm;

Я уже пробовал различные способы экспорта созданной формы в CustomReduxForm, но все равно ничего!

return reduxForm({ 
 
    form: props.formName, 
 
    validate 
 
})(CustomForm); 
 

 
// or 
 

 
const FormWrapped = reduxForm({ 
 
    form: props.formName, 
 
    validate 
 
})(CustomForm); 
 

 
// Non sense, but .. 
 
return FormWrapped; 
 

 
// or 
 
return <FormWrapped />;

Спасибо!

+0

Ваша последняя идея возврата '' должна быть достаточной. Есть ли у вас какие-либо ошибки в этой идее? Если да, то каковы они? Кроме того, не могли бы вы создать JSFiddle/JSBin/Webpackbin, который воспроизводит вашу проблему? – gustavohenke

+0

Спасибо за ответ, теперь я получаю это, чтобы работать, я следил за советом jpdelatorre. Похоже, было больше недостающих частей. Еще раз спасибо! –

ответ

2

Проблема является возвращение заявление CustomReduxForm.

Правильный должен назначить его переменной и использовать синтаксис JSX, как то, что вы сделали в последнем фрагменте.

const WrappedForm = reduxForm(...)(CustomForm); 
return <WrappedForm /> 

Единственное, что вы пропустили это также передать реквизита CustomReduxForm к WrappedForm.

Вы должны будете использовать return <WrappedForm {...props} />

Теперь это вопрос о фиксации других ошибок в коде, как ...

const { fields, handleSubmit } = this.props

Вместо использования const renderFieldset и делать {fields.map(myFieldset => renderFieldset(myFieldset)

Вы можете использовать const Fieldset = ... затем {fields.map((myFieldset, index) => <Fieldset key={index} />)}

Это должно работать, как ожидалось.

0

Каждый компонент React должен иметь метод render().

Поэтому убедитесь, что ваш функциональный компонент CustomReduxForm имеет метод визуализации.

Я думаю, вы должны обернуть возвращение в методе визуализации:

function render() { 
    return reduxForm({ 
     form: props.formName, 
     validate 
    })(CustomForm); 
} 

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

Посмотрите на official redux form documentation, как это обычный способ создания форм:

import React from 'react' 
import { Field, reduxForm } from 'redux-form' 

const SimpleForm = (props) => { 
    const { handleSubmit, pristine, reset, submitting } = props 
    return (
    <form onSubmit={handleSubmit}> 
     <div> 
     <label>First Name</label> 
     <div> 
      <Field name="firstName" component="input" type="text" placeholder="First Name"/> 
     </div> 
     </div> 
     <div> 
     <label>Last Name</label> 
     <div> 
      <Field name="lastName" component="input" type="text" placeholder="Last Name"/> 
     </div> 
     </div> 
     <div> 
     <label>Email</label> 
     <div> 
      <Field name="email" component="input" type="email" placeholder="Email"/> 
     </div> 
     </div> 
     <div> 
     <label>Sex</label> 
     <div> 
      <label><Field name="sex" component="input" type="radio" value="male"/> Male</label> 
      <label><Field name="sex" component="input" type="radio" value="female"/> Female</label> 
     </div> 
     </div> 
     <div> 
     <label>Favorite Color</label> 
     <div> 
      <Field name="favoriteColor" component="select"> 
      <option></option> 
      <option value="ff0000">Red</option> 
      <option value="00ff00">Green</option> 
      <option value="0000ff">Blue</option> 
      </Field> 
     </div> 
     </div> 
     <div> 
     <label htmlFor="employed">Employed</label> 
     <div> 
      <Field name="employed" id="employed" component="input" type="checkbox"/> 
     </div> 
     </div> 
     <div> 
     <label>Notes</label> 
     <div> 
      <Field name="notes" component="textarea"/> 
     </div> 
     </div> 
     <div> 
     <button type="submit" disabled={pristine || submitting}>Submit</button> 
     <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button> 
     </div> 
    </form> 
) 
} 

export default reduxForm({ 
    form: 'simple' // a unique identifier for this form 
})(SimpleForm) 
Смежные вопросы