Простой пример ReactJS для отображения оповещения

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

Это HTML и CSS:

class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
     value: '',
     fname:'',
  };

  this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

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

  handleSubmit(event) {
    event.preventDefault();
    alert('Hello: ' + this.state.fname);
  }

  render() {
    return (
      <div className="example">
        <form onSubmit={this.handleSubmit}>
          <span>Square of:</span>
          <input type="text" value={this.state.value} onChange={this.handleChange} />
          <span>First name:</span>
          <input type="text" value={this.state.fname}  />
          <input type="submit" value="Submit" />
        </form>
        <div className="preview">
          <h1>Square of no is</h1>
          <div>{this.state.value * this.state.value}</div>
        </div>
      </div>
    );
  }
} 

ReactDOM.render(<EssayForm />, document.getElementById('app'));
.example {
  font-family: 'Open Sans', sans-serif;
  display: flex;
  padding: 20px;
  form {
    display: flex;
    align-items: flex-start;
    margin-right: 50px;
    * {
      margin-right: 10px;
    }
  }
  h1 {
    font-size: 20px;
    font-weight: bold;
  }
  .preview {
    white-space: pre;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

Помогите мне создать окно предупреждения с введенным именем пользователя.


person faraz    schedule 07.08.2019    source источник
comment
Вы перезаписываете this.state.fname на event.target.fname, которого не существует и поэтому он не определен. Текущий код: codesandbox.io/s/shy-grass-hkvkz   -  person Chris G    schedule 07.08.2019
comment
почему бы просто не использовать пример, представленный на официальной странице реакции? Он точно показывает, чего вы пытаетесь достичь   -  person kboul    schedule 07.08.2019
comment
@kboul Похоже, это именно то, что использовал OP, пытался расширить его и точно не знал, как это сделать.   -  person Chris G    schedule 07.08.2019


Ответы (4)


Вам не хватает обработчика onChange для имени. Также рекомендуется использовать другой прослушиватель onchange для имени, поскольку вы не хотите обновлять числовое значение при обновлении номера. Вот модифицированная версия кода:

import React from 'react';

export class EssayForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            fname:'',
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleNameChange = this.handleNameChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleNameChange(event){
        this.setState({fname: event.target.value});

    }

    handleSubmit(event) {
        event.preventDefault();
        alert('Hello: ' + this.state.fname);

    }

    render() {
        return (
            <div className="example">
                <form onSubmit={this.handleSubmit}>
                    <span>Square of:</span>
                    <input type="text" value={this.state.value} onChange=
                        {this.handleChange} />
                    <span>First name:</span>
                    <input type="text" value={this.state.fname}  onChange=
                        {this.handleNameChange} />
                    <input type="submit" value="Submit" />
                </form>
                <div className="preview">
                    <h1>Square of no is</h1>
                    <div>{this.state.value * this.state.value}</div>
                </div>
            </div>
        );
    }
}
person reactdesign    schedule 07.08.2019
comment
Я не думаю, что добавление отдельного метода обработчика для каждого <input> в целом является хорошей идеей. - person Chris G; 07.08.2019
comment
Согласен @ChrisG, вы всегда можете передать в функцию изменения, какой ввод вызывает {handleChange}, и соответствующим образом обновить состояние. - person reactdesign; 07.08.2019

Вам нужно создать другой обработчик для изменения текста и правильно обновить состояние fname, а также убедиться, что вы не переопределяете fname при изменении квадратного входного значения.

Проверьте код ниже:

class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
     value: '',
     fname:'',
  };

    this.handleSquareChange = this.handleSquareChange.bind(this);
    this.handleTextChange = this.handleTextChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

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

  handleTextChange(event) {
    this.setState({fname: event.target.value});
  }
 
  handleSubmit(event) {
    event.preventDefault();
    alert('Hello: ' + this.state.fname);
  }

  render() {
    return (
      <div className="example">
        <form onSubmit={this.handleSubmit}>
          <span>Square of:</span>
          <input type="text" value={this.state.value} onChange={this.handleSquareChange} />
          <span>First name:</span>
          <input type="text" value={this.state.fname} onChange={this.handleTextChange} />
          <input type="submit" value="Submit" />
        </form>
        <div className="preview">
          <h1>Square of no is</h1>
          <div>{this.state.value * this.state.value}</div>
        </div>
      </div>
    );
  }
} 

ReactDOM.render(<EssayForm />, document.getElementById('app'));
.example {
  font-family: 'Open Sans', sans-serif;
  display: flex;
  padding: 20px;
  form {
    display: flex;
    align-items: flex-start;
    margin-right: 50px;
    * {
      margin-right: 10px;
    }
  }
  h1 {
    font-size: 20px;
    font-weight: bold;
  }
  .preview {
    white-space: pre;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

person V. Sambor    schedule 07.08.2019
comment
Я не думаю, что добавление отдельного метода обработчика для каждого <input> в целом является хорошей идеей. - person Chris G; 07.08.2019
comment
@ChrisG, вы правы, это можно разложить на множители, я просто хотел показать ему решение его проблемы, а не работать над производительностью;) (но в любом случае это хорошо) - person V. Sambor; 07.08.2019
comment
Конечно, но по моему мнению, вопрос всегда должен учить хорошей практике, если появляется возможность, а не просто решать насущную проблему, иначе он по умолчанию учит плохой практике, и мы продолжим получать студентов w3schools. - person Chris G; 07.08.2019

Вы можете проверить следующий код, чтобы заставить его работать.

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            fname:'',
        };
    }

    handleChange(event, key) {
        let state = {};
        let value = event.target.value;
        state[key] = value;
        this.setState(state);
    }

    handleSubmit(event, name) {
        console.log(name);
        event.preventDefault();
        alert('Hello: ' + this.state.fname);
    }

    render() {
        return (
            <div className="example">
                <form onSubmit={(e) => this.handleSubmit(e)}>
                    <span>Square of:</span>
                    <input type="text"
                           value={this.state.value}
                           onChange={(e) => this.handleChange(e, "value")} />
                    <span>First name:</span>
                    <input type="text"
                           value={this.state.fname}
                           onChange={(e) => this.handleChange(e, "fname")}/>
                    <input type="submit" value="Submit" />
                </form>
                <div className="preview">
                    <h1>Square of no is</h1>
                    <div>{this.state.value * this.state.value}</div>
                </div>
            </div>
        );
    }
}

export default App;
person Manish Bisht    schedule 07.08.2019
comment
Ваш handleChange напрямую манипулирует this.state, чего вы не должны делать. let state = this.state; не создает копию, даже поверхностную. - person Chris G; 07.08.2019
comment
Спасибо @ChrisG за сообщение о проблеме. Я обновил код с исправлением. - person Manish Bisht; 07.08.2019

Нет никакого обработчика изменений для состояния fname.

Пожалуйста, отправьте ссылку

person Double H    schedule 07.08.2019
comment
Технически это не так; В коде OP есть this.setState({fname: event.target.fname});, который действительно вызывается. В любом случае, ответ не может быть просто ссылкой в ​​другом месте. Он должен содержать исправление в тексте. - person Chris G; 07.08.2019