2017-01-12 2 views
6

InputField & Button - это пользовательские компоненты, которые входят в форму для создания формы. Моя проблема заключается в том, как я могу отправить данные обратно, чтобы сформировать так, что нажатие кнопки, я могу стрелять Аякс по форме с данными (имя пользователя & пароля):React - Can Детский компонент Отправить значение Вернуться к родительской форме

export default auth.authApi(
    class SignUpViaEmail extends Component{ 

    constructor(props){ 
     super(props); 
     this.state = { 
     email : "", 
     password : "" 
     }; 
     this.storeEmail = this.storeEmail.bind(this); 
     this.storePassword = this.storePassword.bind(this); 
    } 

    storeEmail(e){ 
     this.setState({ email : e.target.value }); 
    } 

    storePassword(e){ 
     this.setState({ password : e.target.value }); 
    } 

    handleSignUp(){ 
     this.props.handleSignUp(this.state); 
    } 

    render(){ 
     return(
     <div className="pageContainer"> 

      <form action="" method="post"> 
      <InputField labelClass = "label" 
         labelText = "Username" 
         inputId = "signUp_username" 
         inputType = "email" 
         inputPlaceholder = "registered email" 
         inputClass = "input" /> 
      <Button btnClass = "btnClass" 
        btnLabel = "Submit" 
        onClickEvent = { handleSignUp } /> 
      </form> 
     </div> 
    ); 
    } 

    } 
); 

Или это не рекомендуется & я не должен создавать пользовательские дочерние компоненты в форме?

ребенок компонент =>InputField

import React, 
     { Component } from "react"; 

export class InputField extends Component{ 

    constructor(props){ 
    super(props); 
    this.state = { 
     value : "" 
    }; 
    this.onUserInput = this.onUserInput.bind(this); 
    } 

    onUserInput(e){ 
    this.setState({ value : e.target.value }); 
    this.props.storeInParentState({[ this.props.inputType ] : e.target.value }); 
    } 

    render(){ 
    return <div className = ""> 
       <label htmlFor = {this.props.inputId} 
        className = {this.props.labelClass}> 
       {this.props.labelText} 
       </label> 
       <input id = {this.props.inputId} 
        type = {this.props.inputType} 
        onChange = {this.onUserInput} /> 
       <span className = {this.props.validationClass}> 
       { this.props.validationNotice } 
       </span> 
      </div>; 
    } 
} 

Ошибка: Я получаю ошибку e.target is undefined на материнской storeEmail FUNC.

+1

Вы можете передать обработчик событий «keyup» на входы, чтобы состояние родительского компонента постоянно обновлялось. Затем всякий раз, когда handleSignup вызывается, компонент формы уже имеет все необходимое. – theleebriggs

+0

@ rufio86 прав, вам нужно сначала обновить состояние родительского компонента. И вам нужно связать обратный вызов 'handleSignUp', тогда вы получите свое состояние. – hawk

+0

извинения как за @ rufio86 & hawk, просьба уточнить – Kayote

ответ

13

Взаимодействие данных в режиме реального времени g означает, что дочерние компоненты не могут отправлять обратно значения родительским компонентам , если явно не разрешено делать это. Реагирование этого действия заключается в том, чтобы передать обратный вызов дочернему компоненту (см. Facebook's "Forms" guide).

class Parent extends Component { 
    constructor() { 
    this.state = { 
     value: '' 
    }; 
    } 

    //... 

    handleChangeValue = e => this.setState({value: e.target.value}); 

    //... 

    render() { 
    return (
     <Child 
     value={this.state.value} 
     onChangeValue={this.handleChangeValue} 
     /> 
    ); 
    } 
} 

class Child extends Component { 
    //... 

    render() { 
    return (
     <input 
     type="text" 
     value={this.props.value} 
     onChange={this.props.onChangeValue} 
     /> 
    ); 
    } 
} 

Примите к сведению, что родительский компонент обрабатывает состояние, в то время как ребенок компонент только обрабатывает отображение. Facebook's "Lifting State Up" guide - хороший ресурс для изучения того, как это сделать.

Этот способ, Все данные хранятся в родительском компоненте (в состоянии), а дочерние компоненты предоставляются только для обновления этих данных (обратные вызовы передаются как реквизиты). Теперь ваша проблема решена: ваш родительский компонент имеет доступ ко всем требуемым данным (поскольку данные хранятся в состоянии), но ваши дочерние компоненты отвечают за привязку данных к своим отдельным элементам, например, к <input> тегам.

-1

Вы можете добавить «реф имя» в вашем InputField, так что вы можете вызвать некоторую функцию от него, как:

<InputField 
    ref="userInput" 
    labelClass = "label" 
    labelText = "Username" 
    inputId = "signUp_username" 
    inputType = "email" 
    inputPlaceholder = "registered email" 
    inputClass = "input" /> 

Таким образом, вы можете получить доступ к нему с помощью рефов:

this.refs.userInput.getUsernamePassword(); 

Где Функция getUsernamePassword будет находиться внутри компонента InputField, а с возвратом вы можете установить состояние и вызвать свой props.handleSignUp

+0

Хотя это * будет * работать, обычно не рекомендуется прикреплять ссылки к компонентам, а тем более делать это, чтобы получать значения из дочерних компонентов. Эта проблема более немедленно решена путем передачи обратных вызовов, что является способом canon для этого. (См. [Справочное руководство по Facebook] (https://facebook.github.io/react/docs/forms.html)) –

+0

Действительно, подход ref является самым простым способом в его случае, но да, обратные вызовы были бы хорошим выбором слишком. –

+0

refs как строка считаются устаревшим кодом и могут быть удалены: https://facebook.github.io/react/docs/refs-and-the-dom.html –

Смежные вопросы