第二次用户交互后,输入字段上的Value属性发生变化-React

时间:2018-09-22 14:08:59

标签: reactjs

我有一个包含两个输入元素的表单-一个用于名称(type =“ text”),一个用于年龄(type =“ number”)。我在父组件中管理表单状态。我有我的处理程序方法和所有设置。用户输入时,表单状态会更改。同样,name字段上的input value属性会根据当前状态接收其值,但是number字段不会在用户键入时接收到它的值,而是在用户与页面进行第二次交互时(单击其他位置说)
这是我的表单组件:

const Form = (props) => {
    return (
    <div className="col-md-4 form">
      <form id="myForm">
        <div className="form-group">
          <label>Please, enter your name</label>
          <input onChange={props.inputChanged} id="name" type="text" className="form-control" name="name"
                 placeholder="Name" value={props.data.name}/>
        </div>
        <div className="form-group">
          <label>How old are you?</label>
          <input onChange={props.inputChanged} id="age" type="number" className="form-control" name="age"
                 placeholder="Age" value={props.data.age}/>
        </div>
    </div>

以及拥有状态的基于父类的组件:

class DbControls extends Component {

  //INITIAL STATE
  state = {
    name: '',
    age: '',
    greeting: 'hello',
    role: 'admin'
  }

  //HANDLE USER INPUT FOR NAME AND AGE
  inputHandler = (e) => {
    if (e.target.id === 'name') {
      this.setState({name: e.target.value})
    } else if (e.target.id === 'age') {
      this.setState({age: e.target.value})
    }
  }

  //HANDE USER PREFERENCES FOR GREETING AND ROLE
  selectHandler = (e) => {
    if (e.target.id === 'greet') {
      this.setState({greeting: e.target.value})
    } else if (e.target.id === 'role') {
      this.setState({role: e.target.value})
    }
  }


  render() {
    return (
      <div className="container-fluid">
        <div className="row">
          <Form data={this.state} inputChanged={this.inputHandler} selectChanged={this.selectHandler}/>
          <div className="col-md-6 table">
            <Table tableFor="Admins table"/>
            <Table tableFor="Moderators table"/>
          </div>
        </div>
      </div>
    );
  }
}

我不确定这是否是一个实际的问题,但我只是想知道这种行为的原因是什么?

2 个答案:

答案 0 :(得分:1)

根据您的一些评论,我了解您面临的真正问题是DOM属性与值属性不同步。

这是设计使然,有关此问题的讨论很多,它主要与人们对此产生的困惑有关:

  1. jsx值属性/属性
  2. DOM(devtools html)值属性

这些不是同一回事。

还有另一件事要考虑,与密码利用有关。

您可以阅读this issue以获得更好的理解和更多细节。

答案 1 :(得分:0)

根据输入的e.target.namee.target.value简化输入如何设置状态。根据设计,DOM号输入值仅在不集中时才会更新,但状态始终是最新的。

这是一个有效的示例:https://codesandbox.io/s/qzl5knl4kj

formInputs.js

import React, { Fragment } from "react";

export default ({ age, handleChange, name }) => (
  <Fragment>
    <label>Please, enter your name: </label>
    <br />
    <input
      onChange={handleChange}
      type="text"
      className="uk-input"
      name="name"
      placeholder="Name"
      value={name}
      style={{ width: 300, marginBottom: 10 }}
    />
    <br />
    <label>How old are you?</label>
    <br />
    <input
      onChange={handleChange}
      type="number"
      className="uk-input"
      name="age"
      placeholder="Age"
      value={age}
      style={{ width: 300, marginBottom: 10 }}
    />
    <br />
  </Fragment>
);

index.js

import React, { Component } from "react";
import { render } from "react-dom";
import FormInputs from "./formInputs";
import "uikit/dist/css/uikit.min.css";
import "./styles.css";

class App extends Component {
  state = {
    name: "",
    age: "",
    greeting: "hello",
    role: "admin"
  };

  handleChange = ({ target: { name, value } }) => this.setState({ [name]: value });

  handleFormClear = () => this.setState({ age: "", name: "" });

  handleSubmit = e => {
    e.preventDefault();

    const { age, name } = this.state;
    if (!age || !name) return;

    alert(`Name: ${name}, Age: ${age}`);
  };

  render = () => (
    <form onSubmit={this.handleSubmit} style={{ textAlign: "center" }}>
      <h1>Mixed Input Fields</h1>
      <FormInputs {...this.state} handleChange={this.handleChange} />
      <button
        style={{ marginBottom: 20, marginRight: 10 }}
        type="submit"
        className="uk-button uk-button-primary"
      >
        Submit
      </button>
      <button
        style={{ marginBottom: 20 }}
        type="button"
        className="uk-button uk-button-danger"
        onClick={this.handleFormClear}
        disabled={!this.state.name && !this.state.age}
      >
        Clear
      </button>
      <div>
        <pre style={{ margin: "auto", width: 300 }}>
          <code>
            Name: {this.state.name}
            <br />
            Age: {this.state.age}
          </code>
        </pre>
      </div>
    </form>
  );
}

render(<App />, document.getElementById("root"));