最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React.js - how to set state on form submit? - Stack Overflow

programmeradmin4浏览0评论

Newbie React question - I've got myself thoroughly confused trying to follow the docs.

I want a simple text input that on button click, displays the input value below the form. Pretty simple, right?

This is my component so far:

export default class TextInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();
    this.setState({ value: event.target.value });
  }

  render() {
    return (
      <div>
      <form onSubmit={this.handleSubmit}>
        <label>
          <input type="text"  value='' />
        </label>
        <input type="submit" value="Submit" />
      </form>
      <p>{ this.state.value }</p>
      </div>
    );
  }
}

However, it doesn't work at all - the form doesn't display anything when the user types.

What am I doing wrong?

Newbie React question - I've got myself thoroughly confused trying to follow the docs.

I want a simple text input that on button click, displays the input value below the form. Pretty simple, right?

This is my component so far:

export default class TextInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();
    this.setState({ value: event.target.value });
  }

  render() {
    return (
      <div>
      <form onSubmit={this.handleSubmit}>
        <label>
          <input type="text"  value='' />
        </label>
        <input type="submit" value="Submit" />
      </form>
      <p>{ this.state.value }</p>
      </div>
    );
  }
}

However, it doesn't work at all - the form doesn't display anything when the user types.

What am I doing wrong?

Share Improve this question asked Jun 26, 2017 at 20:05 RichardRichard 65.5k134 gold badges356 silver badges568 bronze badges
Add a comment  | 

7 Answers 7

Reset to default 6

Changes:

1. You need to remove the value='' from input element otherwise it will not allow you to type any thing, you are not using any onChange function also.

Ways of using elements:

Controlled Component: Define a onChange function and value property and update that value inside that change function.

Uncontrolled Component: Don't define the value property, use ref to get the value of element.

2. Use ref with input element to get it's value in onSubmit function.

Check this:

class TextInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();
    this.setState({ value: this.element.value });
  }

  render() {
    return (
      <div>
      <form onSubmit={this.handleSubmit}>
        <label>
          <input type="text" ref={el => this.element = el} />
        </label>
        <input type="submit" value="Submit" />
      </form>
      <p>{ this.state.value }</p>
      </div>
    );
  }
}

ReactDOM.render(<TextInput/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>

You need to have a controlled input, you would save the value as the user types into the textfield, then on submit you can get the data form the state.

export default class TextInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
    this.handleSubmit = this.handleSubmit.bind(this);
  }

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

  handleSubmit(event) {
    event.preventDefault();
    //this.setState({ value: event.target.value });
    consoole.log(this.state.value);
  }

  render() {
    return (
      <div>
      <form onSubmit={this.handleSubmit}>
        <label>
          <input type="text" value={this.state.value} onChange={this.onChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
      <p>{ this.state.value }</p>
      </div>
    );
  }
}

This is the conventional way to get the user's input, using a controlled component.

You problem is in

<input type="text"  value='' />

take out the value

<input type="text" />

"value" will set the content to an empty string on every render

When using your handle submit function, the event.target is the form element, which has no value, so nothing is set. The "react way" to handle this is to use something called "controlled inputs". Take a look at how I would implement them with your code:

export default class TextInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      value: ''
    };
    this.handleSubmit = this.handleSubmit.bind(this);
    this.updateInput = this.updateInput.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();
    this.setState({ value: this.state.input });
  }

  updateInput(event) {
    this.setState({input: event.target.value});
  }

  render() {
    return (
      <div>
      <form onSubmit={this.handleSubmit}>
        <label>
          <input type="text"  value={this.state.input} onChange={this.updateInput} />
        </label>
        <input type="submit" value="Submit" />
      </form>
      <p>{ this.state.value }</p>
      </div>
    );
  }
}

Notice especially the new value of input and the change handler I've attached to it.

Didn't work for me at all!! Until I threw in the setState into the onChange itself in the form Return see below - onChange={ e => this.setState({ name : e.target.value })}:

import React, { Component } from 'react';
import logo from '../logo.svg';
import '../App.css';

export default class Dashboard extends Component {
constructor(props){
    super(props);
    this.state = {cakes: [], name: '', review: '', rating: ''}

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
}//compdidmount

handleChange = (event) => this.setState({name: event.target.value, review: event.target.value,rating: event.target.value});

handleSubmit(e) {
    e.preventDefault();
    console.log('A name was submitted: ' + this.state.name + this.state.review + this.state.rating);

  }

  render() {

    const { state } = this;

 const numbers = [1, 2, 3, 4, 5];
 const listItems = numbers.map((number) =>
 // Correct! Key should be specified inside the array.
 <li key={number.toString()}
           value={number}> {number} </li>

);
    return (
      <div className="Dashboard">
        <header className="Dashboard-header">
                    Dashboard
          <h6 className="Dashboard-title">Items pulled from firebase</h6>
        </header>
        <p className="App-intro">
         Items
        </p>
        {listItems}

        <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={state.name} onChange={ e => this.setState({ name : e.target.value }) } />
        </label>
        <label>
          Review:
          <input type="text" value={state.review} onChange={ e => this.setState({ review : e.target.value }) } />
        </label>
        <label>
          Rating:
          <input type="text" value={state.rating} onChange={ e => this.setState({ rating : e.target.value }) } />
        </label>
        <input type="submit" value="Submit" />
      </form>
      </div>
    );
  }
}

Most of the examples seem to be more complicated than they need to be. This example is from the Codevolution's React tutorial:

https://www.youtube.com/watch?v=x9UEDRbLhJE

class TextInput extends Component {
    constructor(props) {
        super(props)
        this.state = {
            mytext: "",
            value: ""
        }
    }

    changeHandler = (e) => {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    submitHandler = (e) => {
        this.setState({
            value: this.state.mytext
        })
        e.preventDefault()
    }

    render() {
        return (
            <form onSubmit={this.submitHandler}>
            <label>
                <input
                name="mytext"
                type="text"
                value={this.state.mytext}
                onChange={this.changeHandler} />
            </label>
            <button
                onSubmit={this.submitHandler}
                type="submit">
                    Submit
                </button>
            <p>{ this.state.value }</p>
            </form>
        )
    }
}

Changes on the form update the state fields so when you hit submit, everything is ready. Each input field is named it's easy to map them back on to their state.

import { useRef } from 'react';

const formField1 = useRef();
const formField2 = useRef();

// Form Submit Handler
const handleFormSubmit = (e) => {
    e.preventDefault();
    const inputField1 = formField1.current.value;
    const inputField2 = formField2.current.value;
    console.log(inputField1, inputField2);
    // do something with values
    }
  };

// Your Form
<form onSubmit={handleFormSubmit}>
    <label>
      <input
        ref={formField1}
        type="text"
        placeholder="Form field 1 placeholder"
      />
    </label>
    <label>
      <input
        ref={formField2}
        type="text"
        placeholder="Form field 2 placeholder"
      />
    </label>
    <input type="submit" value="Submit" />
</form>

The above is an example using the useRef hook! I realize you are using a class based Component, but a functional component makes it so much easier.

发布评论

评论列表(0)

  1. 暂无评论