• React之表单


    第一部分:表单基础

    在React中,修改表单的唯一途径是使用setState方法。举例如下:

      

    class NameForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {value: ''};
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
        this.setState({value: event.target.value});
      }
    
      handleSubmit(event) {
        alert('A name was submitted: ' + this.state.value);
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              Name:
              <input type="text" value={this.state.value} onChange={this.handleChange} />
            </label>
            <input type="submit" value="Submit" />
          </form>
        );
      }
    }
    
    ReactDOM.render(
      <NameForm />,
      document.getElementById('root')
    );

      在codepen的运行代码连接

      

      我们可以看出其运行逻辑:首先将组建渲染到页面,及执行了render(),此时获取的value为空,当我们输入数据时,触发handleChange函数(注意:要提前绑定在当前环境下),然后设置state中的value为用户当前输入值,于是表单元素input获取到最新的state并使用虚拟dom与真实dom作对比,只更新有变化的dom...  当点击提交按钮时,触发了handleSubmit函数。

      值得注意的是:在handleSubmit函数中,我们使用event.preventDefault()阻止了默认行为,即:提交表单后,不会自动reset表单,而是保留之前的用户数据!

    第二部分:textarea表单

      textarea表单和Input表单本身是没有什么区别的,举例如下所示:

    class EssayForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          value: 'Please write an essay about your favorite DOM element.'
        };
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
        this.setState({value: event.target.value});
      }
    
      handleSubmit(event) {
        alert('An essay was submitted: ' + this.state.value);
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              Name:
              <textarea value={this.state.value} onChange={this.handleChange} style={{color:'red','400px',height:'15px'}} />
            </label>
            <input type="submit" value="Submit" />
          </form>
        );
      }
    }
    
    ReactDOM.render(
    <EssayForm/>,
    document.getElementById('root')
    );

       这里我设置了初始状态,所以一开始我们就可以在textarea中看到内容,稍有不同的是,我还在textarea中设置了样式(注意:要用两个curly brace,外面的表示包含js对象,里面的表示包含一个样式对象,当然我们也可以在外面先定义对象然后再传进来)。

      另外,我们还可以直接在css中设置样式,如下所示:

    textarea{
      background:red;
      color:white !important;
    }

      这样,背景颜色为红色,字体为白色。

      注意:因为在React中设置的style是行内样式,优先级较高,故在外联样式中无法覆盖,只有通过使用!important的方式才能成功覆盖。

      另外,将样式对象传入的方法如下:

    render() {
        var myStyle = {
            '400px',
            height:'15px',
            color:'red'
                      }; 
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              Name:
              <textarea value={this.state.value} onChange={this.handleChange} style={myStyle} />
            </label>
            <input type="submit" value="Submit" />
          </form>
        );

    第三部分:select表单

      例子如下所示:

    class FlavorForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {value: 'coconut'};
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
        this.setState({value: event.target.value});
      }
    
      handleSubmit(event) {
        alert('Your favorite flavor is: ' + this.state.value);
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              Pick your favorite La Croix flavor:
              <select value={this.state.value} onChange={this.handleChange}>
                <option value="grapefruit">Grapefruit</option>
                <option value="lime">Lime</option>
                <option value="coconut">Coconut</option>
                <option value="mango">Mango</option>
              </select>
            </label>
            <input type="submit" value="Submit" />
          </form>
        );
      }
    }
    
    ReactDOM.render(
      <FlavorForm />,
      document.getElementById('root')
    );

    连接。

    第四部分:复杂表单

       举例如下所示:

    class Reservation extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          isGoing: true,
          numberOfGuests: 2
        };
    
        this.handleInputChange = this.handleInputChange.bind(this);
      }
    
      handleInputChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
    
        this.setState({
          [name]: value
        });
      }
    
      render() {
        return (
          <form>
            <label>
              Is going:
              <input
                name="isGoing"
                type="checkbox"
                checked={this.state.isGoing}
                onChange={this.handleInputChange} />
            </label>
            <br />
            <label>
              Number of guests:
              <input
                name="numberOfGuests"
                type="number"
                value={this.state.numberOfGuests}
                onChange={this.handleInputChange} />
            </label>
          </form>
        );
      }
    }
    
    ReactDOM.render(
      <Reservation />,
      document.getElementById('root')
    );

    连接

    第五部分:lifting state up

      举例如下:

    const scaleNames = {
      c: 'Celsius',
      f: 'Fahrenheit'
    };
    
    class TemperatureInput extends React.Component {
      constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.state = {value: '545445'};
      }
    
      handleChange(e) {
        this.setState({value: e.target.value});
      }
    
      render() {
        const value = this.state.value;
        const scale = this.props.scale;
        return (
          <fieldset>
            <legend>Enter temperature in {scaleNames[scale]}:</legend>
            <input value={value}
                   onChange={this.handleChange} />
          </fieldset>
        );
      }
    }
    
    class Calculator extends React.Component {
      render() {
        return (
          <div>
            <TemperatureInput scale="c" />
            <TemperatureInput scale="f" />
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <Calculator />,
      document.getElementById('root')
    );

     链接。

    两个input联动

    const scaleNames = {
      c: 'Celsius',
      f: 'Fahrenheit'
    };
    
    function toCelsius(fahrenheit) {
      return (fahrenheit - 32) * 5 / 9;
    }
    
    function toFahrenheit(celsius) {
      return (celsius * 9 / 5) + 32;
    }
    
    function tryConvert(value, convert) {
      const input = parseFloat(value);
      if (Number.isNaN(input)) {
        return '';
      }
      const output = convert(input);
      const rounded = Math.round(output * 1000) / 1000;
      return rounded.toString();
    }
    
    function BoilingVerdict(props) {
      if (props.celsius >= 100) {
        return <p>The water would boil.</p>;
      }
      return <p>The water would not boil.</p>;
    }
    
    class TemperatureInput extends React.Component {
      constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
      }
    
      handleChange(e) {
        this.props.onChange(e.target.value);
      }
    
      render() {
        const value = this.props.value;
        const scale = this.props.scale;
        return (
          <fieldset>
            <legend>Enter temperature in {scaleNames[scale]}:</legend>
            <input value={value}
                   onChange={this.handleChange} />
          </fieldset>
        );
      }
    }
    
    class Calculator extends React.Component {
      constructor(props) {
        super(props);
        this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
        this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
        this.state = {value: '', scale: 'c'};
      }
    
      handleCelsiusChange(value) {
        this.setState({scale: 'c',value});
      }
    
      handleFahrenheitChange(value) {
        this.setState({scale: 'f',value});
      }
    
      render() {
        const scale = this.state.scale;
        const value = this.state.value;
        const celsius = scale === 'f' ? tryConvert(value, toCelsius) : value;
        const fahrenheit = scale === 'c' ? tryConvert(value, toFahrenheit) : value;
    
        return (
          <div>
            <TemperatureInput
              scale="c"
              value={celsius}
              onChange={this.handleCelsiusChange} />
            <TemperatureInput
              scale="f"
              value={fahrenheit}
              onChange={this.handleFahrenheitChange} />
            <BoilingVerdict
              celsius={parseFloat(celsius)} />
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <Calculator />,
      document.getElementById('root')
    );

    链接

      

     值得注意的是: 如果几个组件都需要访问(获取)相同的state, 那么这是一个我们需要将state提升(listing)到他们几个共同的相同的祖先组件中的信号!在我们的例子中,就是Calculator。 我们存储了value 和 scale 在Calculator的state中。

     两个input将会保持同步,因为他们基于相同的state。

     不管你在哪个input中输入,this.state.value和this.state.scale都会更新。

     即通常,如果一个组件需要state来render,这时我们可以将之添加到这个组件中,但是如果另外一个组件也需要这个state,我们就可以把这个state提升到两者最近的祖先中去。相反于尝试着去同步两个不同组件的state,我们应当依赖于top-down data flow,即React中独特的自上而下的数据流。

      入门react不得不看的例子。

  • 相关阅读:
    [Python自学] PyQT5-Web控件、与JavaScript交互
    [Python自学] PyQT5-选项卡窗口、堆栈窗口、停靠窗口、子窗口
    [Python自学] PyQT5-窗口风格、窗口样式、GIF动画、窗口透明
    [Python自学] PyQT5-子线程更新UI数据、信号槽自动绑定、lambda传参、partial传参、覆盖槽函数
    [Python自学] PyQT5-信号与槽
    [Python自学] PyQT5-菜单栏、工具栏、状态栏
    [Python自学] PyQT5-控件拖拽、剪切板
    [Python自学] PyQT5-各种QDialog对话框
    [Python自学] PyQT5-QSpinBox、QSlider控件
    Linux操作系统分析 | 课程学习总结报告
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/6361398.html
Copyright © 2020-2023  润新知