【问题标题】:React: Search form input not clearing from state by setting state of input to empty array反应:通过将输入状态设置为空数组来搜索表单输入未从状态中清除
【发布时间】:2019-04-08 17:04:05
【问题描述】:

如果我在表单重置方法中使用this.setState({formValues:[]}),我的表单重置按钮不会清除输入的状态。尽管在将输入属性设置为type="search" 时出现的输入字段中按下小 x,但 formValues 确实会被重置。我的输入最初是在这里用我的输入法设置的:

handleInputChange = (key, value) => {
   const newFormValues = Object.assign({}, this.state.formValues, {[key]: value});
   this.setState({ formValues: newFormValues })
};

这是我的表单重置方法..

handleFormReset = () => {
  this.setState({formValues:[]})
  this.setState({contracts:[]})
}

此外,输入中的数据不会从 DOM 中删除。如果我将重置按钮设置为type="reset",那么 DOM 会清除,但状态仍然不清除。

这里是搜索表单组件..

<form className="form-inline col-md-12" onReset={this.props.handleFormReset}>

{this.props.labels.map(label => (
  <div className="card border-0 mx-auto" style={styles} key={label.Id}>
       <ul className="list-inline ">
          <span>
            <li>
              <Labels  htmlFor={label.DisplayName} >{label.DisplayName}:</Labels>
            </li>
            <li >
              <Input  
                key={label.Id}
                onChange={(event) => {
                  this.props.handleInputChange(label.DataField, event.target.value)}}
                value={(this.props.newFormValues) }
                type="text"
                maxLength="999"
                style={{height:34}}
                name="value"

                className={"form-control mb-2 mr-sm-2"} 
                id={label.DataField}
              />
            </li> 
          </span>
      </ul>
  </div>
))}

  <div className=" col-sm-12">

  <Button
        style={{ float: "left", marginBottom: 10 }} 
        className="btn btn-success"
        type="submit"
        onClick={this.props.handleFormSubmit}
      >
        Search
      </Button>

      <Help />

      <Button
        style={{ float: "left", marginBottom: 10 }} 
        className="btn btn-secondary"
        onClick={this.props.clear}
      >
        Reset
      </Button>


  </div>

  </form>

以下是从 api 获取数据的方式。 我的输入标签..

(7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {Id: 0, DisplayName: "Description", DataValue: "", DataType: "Text", DataField: "IDXT004"}
1: {Id: 1, DisplayName: "Supplier Name", DataValue: "", DataType: "Text", DataField: "IDXT003"}
2: {Id: 2, DisplayName: "Contract #", DataValue: "", DataType: "Number", DataField: "IDXT001"}
3: {Id: 3, DisplayName: "Working Contract ID", DataValue: "", DataType: "Text", DataField: "IDXT002"}
4: {Id: 4, DisplayName: "Sourcing Event", DataValue: "", DataType: "Text", DataField: "IDXT011"}
5: {Id: 5, DisplayName: "Effective Date", DataValue: "", DataType: "Date", DataField: "IDXT005"}
6: {Id: 6, DisplayName: "Expiration Date", DataValue: "", DataType: "Date", DataField: "IDXT006"}
length: 7

我的结果数据 api..

(2) [{…}, {…}]
0: {Id: 0, Fields: Array(7), DocImage: {…}}
1: {Id: 1, Fields: Array(7), DocImage: {…}}
length: 2

并进一步细分..

0:
DocImage: {sfKey: 6, sfScanIndex: 6, sfFilename: "2222_1.PDF", sfBatchID: 12898, sfFileUnredact: null, …}
Fields: Array(7)
0: {Id: 0, DisplayName: "Description", DataValue: "2018 Summer Camp CEA between the City, NORD and Infinity Educational Advantage, LLC dba IEANOLA", DataType: "Text", DataField: "IDXT004"}
1: {Id: 1, DisplayName: "Supplier Name", DataValue: "Infinity Educational Advantage, LLC", DataType: "Text", DataField: "IDXT003"}
2: {Id: 2, DisplayName: "Contract #", DataValue: "2222", DataType: "Number", DataField: "IDXT001"}
3: {Id: 3, DisplayName: "Working Contract ID", DataValue: "4321", DataType: "Text", DataField: "IDXT002"}
4: {Id: 4, DisplayName: "Sourcing Event", DataValue: "", DataType: "Text", DataField: "IDXT011"}
5: {Id: 5, DisplayName: "Effective Date", DataValue: "03/09/2018", DataType: "Date", DataField: "IDXT005"}
6: {Id: 6, DisplayName: "Expiration Date", DataValue: "03/06/2019", DataType: "Date", DataField: "IDXT006"}
length: 7

【问题讨论】:

    标签: reactjs dom reset


    【解决方案1】:

    您需要在输入元素上设置value={this.state.someValue[someProperty]}

    将对象设置为空对象似乎不起作用,因为 React 并不意味着跟踪深层对象。我的解决方法是将深层对象中的所有值设置为空字符串。

    最后,我也更喜欢使用JSON.parse(JSON.stringify(variable)),因为它可以制作真正的深层副本。唯一需要注意的是它不会复制引用/函数。

    这是一个具有多个输入的工作示例:

    let initialState = {
      formValues: {}
    }
    
    let apiResponse = [
      {Id: 0, DisplayName: "Description", DataValue: "", DataType: "Text", DataField: "IDXT004"},
      {Id: 1, DisplayName: "Supplier Name", DataValue: "", DataType: "Text", DataField: "IDXT003"},
      {Id: 2, DisplayName: "Contract #", DataValue: "", DataType: "Number", DataField: "IDXT001"},
      {Id: 3, DisplayName: "Working Contract ID", DataValue: "", DataType: "Text", DataField: "IDXT002"},
      {Id: 4, DisplayName: "Sourcing Event", DataValue: "", DataType: "Text", DataField: "IDXT011"},
      {Id: 5, DisplayName: "Effective Date", DataValue: "", DataType: "Date", DataField: "IDXT005"},
      {Id: 6, DisplayName: "Expiration Date", DataValue: "", DataType: "Date", DataField: "IDXT006"},
    ]
    
    class App extends React.Component {
      
      constructor(props) {
        super(props)
        this.state = initialState
      }
      
      handleInputChange = (e) => {
        let newValues = JSON.parse(JSON.stringify(this.state.formValues))
        newValues[e.target.name] = e.target.value
        this.setState({
          formValues: newValues
        })
      }
      
      clear = () => {
        let emptyValues = JSON.parse(JSON.stringify(this.state.formValues))
        Object.keys(emptyValues).forEach(key => emptyValues[key] = "")
        this.setState({
          formValues: emptyValues
        })
      }
      
      clearField = (dataField) => {
        let newValues = JSON.parse(JSON.stringify(this.state.formValues))
        newValues[dataField] = ""
        this.setState({
          formValues: newValues
        })
      }
      
      render() {
        return (
          <div>
            <table><tbody>
            {
              apiResponse.map(res => {
                return (<tr key={res.Id}>
                          <td>{res.DisplayName}</td>
                          <td><input type={res.DataType}
                                     value={this.state.formValues[res.DataField]}
                                     name={res.DataField}
                                     onChange={this.handleInputChange}/></td>
                          <td><button onClick={e => this.clearField(res.DataField)}>X</button></td>
                          <td>&nbsp;State: {this.state.formValues[res.DataField]}</td>
                        </tr>)
              })
            }
            </tbody></table>
            <br/>
            <button onClick={this.clear}>Clear</button>
          </div>
        )
      }
    }
    
    ReactDOM.render((<App/>), document.getElementById('testing'));
    <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="testing">

    【讨论】:

    • 对不起,我应该补充说输入值是value={this.props.newFormValues }
    • 刚刚更改了我的代码以适用于多个输入。似乎效果最好的是我手动清空对象的值,但保留键。
    • 只是稍微改了一下,以编程方式清空键/值对
    • 好的,谢谢。尝试在您的代码中实现。我的表单是从 api 动态创建的,因此我无法静态更改每个输入的值。
    • 如果您将该信息与您的 API 中的示例数据一起添加到您的问题中,我可以尝试进一步帮助您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 2018-12-30
    • 2018-01-18
    • 2018-06-16
    • 2019-09-11
    • 2020-04-13
    • 2021-03-16
    相关资源
    最近更新 更多