2
votes

I'm confused as to why React insists that I give my controlled text input components their own internal state. I followed the official documentation for creating a controlled input, and React is squawking at me via the console:

*warning.js:36 Warning: ClientInfoTextInput is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.

render() {
    return (
      <input type="text"
        className={styles.ClientInfoTextInput}
        value={this.props.propToPass} 
        onChange={this.props.propMethodToPass}
      />
    )

So why can't I pass down state via props to a controlled input component without React getting upset?

1
It is hard to tell without the full component code being shown. Is the component name ClientInfoTextInput? If so I think your problem is that when this is initialized "this.props.propToPass" is undefined. You could do a check for undefined and then pass a default value if it is. - Eric G
Please show the entire file, it makes it easier for us to understand whats going on. More then likely what @ericg said is your problem but we wont know until we see more - finalfreq

1 Answers

3
votes

It's hard to debug your component without seeing the full code, but one way of passing down the state via props to a controlled input component is as follows: http://codepen.io/PiotrBerebecki/pen/bwLjaE

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      textInParent: ''
    };
    this.handleTextFromChild = this.handleTextFromChild.bind(this);
  }

  handleTextFromChild(data) {
    this.setState({
      textInParent: data
    });
  }

  render() {
    return (
      <div>
        <InputForm propMethodToPass={this.handleTextFromChild}
                   propToPass={this.state.textInParent} /> 
      </div>
    );
  }
}


class InputForm extends React.Component {
  render() {
    return (
      <div>
        <input type="text"
               value={this.props.propToPass}
               onChange={(event) => this.props.propMethodToPass(event.target.value)} />
        <p>Text received from Parent via props: {this.props.propToPass}</p>
      </div>
    );
  }
}


ReactDOM.render(
  <App />,
  document.getElementById('app')
);