2016-06-02 2 views
0

У меня есть компонент презентации, который использует функцию из своего контейнерного компонента в качестве опоры. Я хочу вернуть ref в качестве аргумента с функцией обратно в компонент контейнера. Но он возвращается как undefined.React: отправить ref обратно в компонент контейнера?

(То, что я хочу добиться того, чтобы отправить адрес электронной почты, пользователь вставить в форму в компоненте представления, обратно к компоненту контейнера, так что я могу обработать его там.)

Любое предложение о том, как сделать эта работа?

компонент Контейнер

class EmailInputContainer extends Component { 
    addEmailToList(childComponent){ 
    console.log(childComponent.refs) 
    } 
    render(){ 
    return(
     <EmailInputView addEmailToList={this.addEmailToList}/> 
    ) 
    } 
} 

Презентация компонента

const EmailInputView = (functions) => (
    <Grid style={Styles.emailInputView.container} verticalAlign='middle'> 
    <Cell width='5/12' style={Styles.smallText('black', 1.1, 1.5, 'left')}> 
     <p>Enter your mail and we'll keep you<br />posted with news and updates!</p> 
    </Cell> 
    <Cell width='5/12' align='right'> 
     <form onSubmit={functions.addEmailToList(this)}> 
     <input style={Styles.emailInputForm.emailInput} ref='emailInput' type="text" name="email" placeholder="Your email address" /> 
     <input style={Styles.emailInputForm.submitButton} type="submit" value="Submit" /> 
     </form> 
    </Cell> 
    </Grid> 
) 

ответ

4

Имхо лучшая практика будет пройти OnChange обработчик из, как пропеллер к вашему EmailInputView как:

class EmailInputContainer extends Component { 

    handleChange: function(event) { 
     this.setState({myEmail: event.target.value}); 
    } 

    render(){ 
     return(
     <EmailInputView onChange={this.handleChange.bind(this)} /> 
    ) 
    } 
} 

и:

<input onChange={this.props.onChange} style={Styles.emailInputForm.emailInput} type="text" /> 

в самом EmailInputView. Работает с

<form onSubmit={this.props.onChange}> 
    ... 
</form> 

тоже (нету проверил событие у, возможно, придется немного изменить обработчик в EmailInputContainer).

В этом случае вам не нужно передавать рефери, который лучше подходит для философии. Imho, вы никогда не должны передавать ref так, как хотите, и используете только ссылки refs в компоненте, в котором находитесь, когда другого пути нет.

необязательный (если и не хотят, чтобы отправить форму):

class EmailInput extends Component { 

    onChange(event) { 
    this.setState({myEmail: event.target.value}); 
    } 

    onSubmit() { 
    this.props.onChange(this.state.myEmail); //u should rename the prop i just named it so it fits with the example of the parent component above 
    } 

    render() { 
    return (
     <Cell> 
      <input onChange={this.onChange} /> 
      <button onClick={this.onSubmit} /> 
     </Cell> 
    ); 
    } 

} 

нет необходимости использовать форму на всех, если вы не хотите, чтобы предотвратить его functionalitly впоследствии. Если вы все еще хотите опубликовать данные без перезагрузки страницы, вы должны в любом случае реализовать вызов Ajax.

+0

Ницца, спасибо. Зачем вызывать функцию для каждого нажатия клавиши ('onChange'), а не только' onSubmit'? Как прослушать кнопку отправки в этом решении? И как я могу предотвратитьDefault (я не повезло 'event.preventDefault()')? – allegutta

+0

im не уверен, какие данные вы получите onSubmit, но из-за этого было бы лучше использовать это, потому что вам это понадобится, чтобы знать, когда форма была отправлена, и вы не обрабатываете строки, содержащие половину электронной почты все время. попробуйте. – Aligertor

+0

Я был просто доверен на передачу обработчика вместо ref - потому что это важный момент, чтобы получить imho – Aligertor

0

В компоненте презентации захватите узел ref через функцию обратного вызова, когда он отображает, затем передайте значение узла обратно вашему родителю при отправке.

let inputNode 

const EmailInputView = (functions) => (
    <Grid style={Styles.emailInputView.container} verticalAlign='middle'> 

    ... 

    <Cell width='5/12' align='right'> 
     <form 
     onSubmit={() => functions.addEmailToList(inputNode.value)} <-- update here 
     > 
     <input style={Styles.emailInputForm.emailInput} 

      ref={node => inputNode = node} <-- this is what you want 

      type="text" name="email" placeholder="Your email address" /> 
     <input style={Styles.emailInputForm.submitButton} type="submit" value="Submit" /> 
     </form> 
    </Cell> 
    </Grid> 
) 

Затем обновите ваш обработчик:

addEmailToList(value){ 
    console.log(value) 
} 

Таким образом, это решение является большим, особенно если у вас нет одного из родителей, который ничего обработки, такие как диспетчерская действие Redux непосредственно из компонента, который имеет те поле ввода. Тем не менее, ответ на вопрос Алигера.

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