2

Here's my fiddle

https://codepen.io/seunlanlege/pen/XjvgPJ?editors=0011

I have two inputs and I'm trying to use one method to handle the onChange event for any input field.

I've torn the internet apart looking for a solution but came up with nothing.

I'm using es6 please how do I go about this?

class Form extends React.Component {
  `constructor(props) {
    super(props);
    this.state = {text:{
      e:'hi',
      c:''
    }};
    this.handleSubmit = this.handleSubmit.bind(this);
  }`

  `handleChange(event,property) {
    const text = this.state.text;
      text[property] = event.target.value;
      this.setState({text});
  }`

  `handleSubmit(event) {
    alert('Text field value is: ' + this.state.text.e);
  }`

  `render() {
    return (
      <div>
        <div>{this.state.text.e}</div>
        <input type="text"
          placeholder="Hello!"
          value={this.state.text.e}
          onChange={this.handleChange.bind(this)} />
        <input type="text"
          placeholder="Hello!"
          value={this.state.text.c}
          onChange={this.handleChange.bind(this)} />
        <button onClick={this.handleSubmit}>
          Submit
        </button>
      </div>
    );
  }
}`

ReactDOM.render(
  `<Form />`,
  document.getElementById('root')
);
4
  • 1
    Please put your code in the question, using the snippet tool. Links go stale fast... Commented Nov 1, 2016 at 10:18
  • i can't, i keep getting formatting error. Commented Nov 1, 2016 at 10:30
  • Y̶o̶u̶ ̶c̶a̶n̶ ̶u̶s̶e̶ ̶t̶h̶e̶ ̶t̶i̶d̶y̶ ̶b̶u̶t̶t̶o̶n̶.̶ - Should you be returning HTML without putting it in a string? That sounds wrong to me Commented Nov 1, 2016 at 10:33
  • it's not working, can you please look at the pen and tell me what's wrong with my code? Commented Nov 1, 2016 at 10:37

2 Answers 2

3

You have not passed the propert to the handeChange function. pass it like this.handleChange.bind(this, 'e') and also the order of receiving props is wrong, property will be the first argument and then the event and not the reverse.

Code:

class Form extends React.Component {
  constructor(props) {
    super(props);
    this.state = {text:{
      e:'hi',
      c:''
    }};
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(property, event) {
    console.log(event.target.value);
    const text = {...this.state.text};
      text[property] = event.target.value;
      this.setState({ text }); //or you can use the shorthand here. ES6 is awesome <3
  }

  handleSubmit(event) {
    alert('Text field value is: ' + this.state.text.e);
  }

  render() {
    return (
      <div>
        <div>{this.state.text.e}</div>
        <div>{this.state.text.c}</div>
        <input type="text"
          placeholder="Hello!"
          value={this.state.text.e}
          onChange={this.handleChange.bind(this, 'e')} />
        <input type="text"
          placeholder="Hello!"
          value={this.state.text.c}
          onChange={this.handleChange.bind(this, 'c')} />
        <button onClick={this.handleSubmit}>
          Submit
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById('root')
);

CodePen

Sign up to request clarification or add additional context in comments.

Comments

2

One way to do this would be to give each of your inputs a name attribute and set the state based on that:

class Form extends React.Component {
  constructor(props) {
    super(props);
    this.state = { text: {
      e: 'hi',
      c: ''
    } };
    this.onChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(e) {
    var oldState = this.state.text;
    var newState = { [e.target.name]: e.target.value };
    
    // I have to assign/join because you've put the text state in a parent object.
    this.setState({ text: Object.assign(oldState, newState) });
  }

  handleSubmit(event) {
    alert('Text field value is: ' + this.state.text.e);
  }

  render() {
    console.log(this.state);
    return (
      <div>
        <div>{this.state.text.e}</div>
        <input type="text"
          placeholder="Hello!"
          name="e"
          value={this.state.text.e}
          onChange={this.onChange} />
        <input type="text"
          placeholder="Hello!"
          name="c"
          value={this.state.text.c}
          onChange={this.onChange} />
        <button onClick={this.handleSubmit}>
          Submit
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById('View')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.min.js"></script>
<div id="View"></div>

Also, there are so-called two-way binding helpers. As I understand they still show mixins in React's documentation, so you are probably better off with third party libraries like react-link-state:

this.state = {
  username: '',
  password: '',
  toggle: false
};

<input type="text" valueLink={linkState(this, 'username')} />
<input type="password" valueLink={linkState(this, 'password')} />
<input type="checkbox" checkedLink={linkState(this, 'toggle')} />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.