可编辑的表单 ReactJS

IT技术 reactjs react-redux
2021-04-16 15:26:01

import React, { Component } from 'react';
let _ = require('lodash');

import {bindActionCreators} from "redux";
import {connect} from 'react-redux';

import {fetchedBeaconsEdit} from '../../actions/';
import {editBeacon} from '../../actions/index';

// TODO - come up with a decent name

class InfoRow extends Component {

    render() {
        return (

            <tr>
                <td>
              { this.props.beacon === "name" 
                || this.props.beacon === "major" 
                || this.props.beacon === "minor" 
                || this.props.beacon === "beaconType" ?
                  <span>{this.props.beacon}<span className="font-css top">*</span></span>:
                  <span>{this.props.beacon}</span>
              }

                </td>
                <td>

                { this.props.beacon !== "beaconType" && 
                  this.props.beacon !== "uuid" && 
                  this.props.beacon !== "status" && 
                  this.props.beacon !== "store"&&
                  this.props.beacon !== "group" ?
                <div>
                    <input type="text"
                       className="form-control"
                       defaultValue={this.props.beaconValue}
                       name={this.props.beaconValue}
                       onChange={(e) =>this.props.handleInputChangeProp(e.target.value)}
                    /></div>:

                    this.props.beacon === "uuid" && this.props.beacon === "status" && this.props.beacon=== "store"?
                  <span></span>:

                    this.props.beacon === "beaconType"?

                    <select defaultValue={this.props.beaconValue} name={this.props.beaconValue} className="form-control" onChange={(e) =>this.props.handleInputChangeProp(e.target.value)}>
                      
                      <option name="ibeacon">IBEACON</option>
                      <option name="eddystone">EDDYSTONE</option>
                    </select>:this.props.beaconValue

                    

                }



                </td>
            </tr>
        )
    }
}

class BeaconEdit extends Component {

  constructor(props){
    super(props);
    this.state = {
            
        };
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }

  handleInputChange(beacon, value) {

        this.setState({
            [beacon]: value
        });
    }

 handleClick = () =>{
       Object.keys(this.props.ebcn).map((key)=> {
        if (this.state[key] !== undefined) {
          this.props.editBeaconGroup[key]=this.state[key];
        }
            
       })
        this.props.handleSubmitProp(this.props.editBeaconGroup);
  }
 
    render() {

        const rows = [];
        let a = this.props.ebcn;

        

       Object.keys(this.props.ebcn).map((keyName, keyIndex) =>{

          if (keyName === "store" || keyName === "group") {
            return rows.push(<InfoRow beacon={keyName} beaconValue={a[keyName].name.toString()} name={this.state[keyName]} key={keyIndex} handleInputChangeProp={(inp) =>this.handleInputChange(keyName, inp)}/>);
          }else{
            return rows.push(<InfoRow beacon={keyName} beaconValue={a[keyName].toString()} name={this.state[keyName]} key={keyIndex} handleInputChangeProp={(inp) =>this.handleInputChange(keyName, inp)}/>);
       }
       });

        return (


            <div className="col-md-6">
                <div className="">

                  <table className="table table-clear">
                    <tbody>
              
                    {rows}
                    
                    </tbody>
                  </table>
                 </div>
                 <div className="px-1" >
                        <button className="btn btn-sm btn-info btn-size btn-block" onClick={this.handleClick}>Save</button>
                 </div>
          </div>

        )

    }


}

class BeaconDetailEditComponent extends Component {
  
  constructor(props){
    super(props);
    this.state = {
        editbeacons: {}
        };
        this.handleSubmit = this.handleSubmit.bind(this);

        this.validateName = this.validateName.bind(this);
        this.validateMajor = this.validateMajor.bind(this);
        this.validateMinor = this.validateMinor.bind(this);
    }

    validateMinor = (minor) => {
      var re = /^[0-9]+$/;
      return re.test(minor);
    }

    validateMajor = (major) => {
      var re = /^[0-9]+$/;
      return re.test(major);
    }

    validateName = (name) => { 
      var re = /^[A-Za-z ]+$/;
      return re.test(name); 
    };


  handleSubmit (beaconedited) {

    console.log(beaconedited.name);

    if (!this.validateName(beaconedited.name)) { 
              alert('Name can not be an integer')  
          }

    else if (!this.validateMajor(beaconedited.major)) { 
              alert('Major number can only be an integer')  
          }

        else if (beaconedited.major.length > 5) {
          alert('Major number can not exceed 5 digits')
        }

        else if (!this.validateMinor(beaconedited.minor)) { 
              alert('Minor number can only be an integer')  
          }

        else if (beaconedited.major > 65535) {
          alert('Major number can not exceed the limit of 65535')
        }

        else if (beaconedited.minor > 65535) {
          alert('Minor number can not exceed the limit of 65535')
        }

    else {

      this.props.editBeacon(beaconedited, this.props.location.query.id);
    
  }
    }

  componentWillMount = () => {
        this.props.fetchedBeaconsEdit(this.props.location.query.id);  
    };

  
  render() {
    
    return (
        <div className="container px-3 mr-3">
            <div>
              <div className="col-md-6 col-md-offset-3"><h1>Edit Beacon Information</h1></div>
            </div>
            <br/>
            <br/>
                { this.props.ebcn != null?
            <div>
                <BeaconEdit ebcn={this.props.ebcn} handleSubmitProp={this.handleSubmit} editBeaconGroup={this.state.editbeacons}/>
            </div> :
                    <center><img className="gif-size" src={'img/avatars/default.gif'} alt="Loading"/></center>

            }
        </div>
    )
  }
}

function mapStateToProps(state) {
    return {
        eBeacon: state.eBeacon,
        ebcn: state.beacons
    }

}


function matchDispatchToProps(dispatch){
    return bindActionCreators({editBeacon: editBeacon, fetchedBeaconsEdit: fetchedBeaconsEdit}, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(BeaconDetailEditComponent);

这是我现在得到的输出

在此处输入图片说明

我已经提供了代码片段我正在做的是我已经从服务器获取值并显示在字段中我正在将此页面作为可编辑表单我现在想要做的是获取更改或更改的值用户并在控制台中打印它们。我已经应用了 handleInputChange 并在更改时显示了更改的值,但我想在单击按钮时在控制台中看到这些值,以及如何操作?

2个回答

首先,你改变状态的方式不好。您将新状态设置为只有一个属性,即被修改的字段的名称和值。

关于如何打印您正在修改的字段的值,您应该在句柄更改方法中执行控制台日志。

也就是说,您的代码应该如下所示:

handleInputChange(event) {

    //const {name, value} = event.target;
    //const oldState = this.state;
    //const newState = Object.assign({},oldState,{[name]:value});
    //this.setState(newState);

    this.setState({
        [event.target.name]: event.target.value
    });

    //printing the input name and value as it is being modified.
    console.log(name + ":" + value);

    //if you want to see the value of the current state uncomment the line below
    //console.log("State=" + JSON.stringify(newState));

}

printState = () => {
  console.log("State="+JSON.stringify(this.state));
}

有关如何使用分配方法修改对象的更多信息,请参阅:MDN doc on Object.assign()

如果要在单击保存按钮时打印当前状态,请向按钮添加 onClick 属性,如下面的代码所示:

<button value="Save" onClick={this.printState}/>
@cdaiga 你改变状态的方式不好。您将新状态设置为只有一个属性- 我不同意。setState执行下一个状态对象到当前状态的浅合并,因此新状态不会只有单个属性。请查看 React 文档:facebook.github.io/react/docs/react-component.html#setstate
2021-05-25 15:26:01
按钮已经添加,因为您可以看到旅馆代码,但它对您的建议没有帮助
2021-05-29 15:26:01
我只是在我的答案中添加了更多内容。
2021-05-30 15:26:01
你能提供解决方案吗?
2021-06-08 15:26:01
我明白了,但我想在点击保存按钮时打印到控制台,而且我想在点击时打印每个值,无论它是否已更改
2021-06-14 15:26:01

将信息行更改为

class InfoRow extends Component {

    render() {
        return (

            <tr>
                <td>
                  {this.props.beacon}
                </td>
                <td>
                <input type="text"
                   className="form-control"
                   defaultValue={this.props.beaconValue}
                   value={this.props.name}
                   name={this.props.beaconValue}
                   onChange={(e) =>this.props.handleInputChangeProp(e.target.value)}
                />
                </td>
            </tr>
        )
    }
}

并渲染到

Object.keys(this.props.ebcn).map((keyName, keyIndex) =>{

          return rows.push(<InfoRow beacon={keyName} beaconValue={a[keyName].toString()} name={this.state[keyName]} key={keyIndex} handleInputChangeProp={(inp) =>this.handleInputChange(keyName, inp)}/>);
       });

handleInputChange(beacon, value) {

        this.setState({
            [beacon]: value
        });
    }

并处理点击

 handleClick = () =>{
       Object.keys(this.props.ebcn).map((key)=> {
            console.log(this.state[key]);
       }))
  }
第二个错误是因为上下文绑定,第一个是因为最初 this.state[keyName] 是 undefined
2021-05-24 15:26:01
试试这个解决方案,让我知道它是否有效,当然它没有经过测试,可能有一些错误
2021-05-29 15:26:01
在按钮上单击无法读取此 console.log(this.state[key]) 中未定义的属性“状态”;
2021-06-02 15:26:01
警告:InfoRow 正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控制切换到受控制(反之亦然)。决定在组件的生命周期内使用受控或非受控输入元素
2021-06-08 15:26:01
语法错误已删除,但由于未定义“信标”而在此行中出现错误 return rows.push(<InfoRow beacon={keyName} beaconValue={a[keyName].toString()} name={this.state[beacon] } key={keyIndex} handleInputChangeProp={(inp) =>this.handleInputChange(keyName, inp)}/>); });
2021-06-17 15:26:01