反应,从组件中拉出状态

时间:2019-02-22 10:41:07

标签: reactjs

我有一个看起来像这样的表格:

enter code here

底部是表单状态的相关部分,强制转换为此组件中的JSON。

当您单击“添加其他”时,它将添加另一对字段。这些字段对是子组件CountryFieldRow

在子组件中,当编辑字段时,子状态将正确更新。

如何在父对象中获取状态更新,以便可以更新打印的JSON?

编辑,添加了代码:

import React, { Component } from 'react';
import CountryFormRow from "./CountryFormRow"

class CountryForm extends React.Component {
  constructor(props) {
    super(props)
    this.state = {rules: props.rules}
    this.handleDelete = this.handleDelete.bind(this)
    this.handleAdd = this.handleAdd.bind(this)
    this.handleInputChange = this.handleInputChange.bind(this)

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

  handleDelete(event) {
    this.setState({rules: this.state.rules.slice(0, -1)})
    console.log(rules)
  }

  handleAdd(even) {
    this.setState({rules: this.state.rules.concat({what: "country"})})
  }

  handleChange(event){
    console.log(event)
  }


  render() {
    // var my_json = JSON.stringify(this.state.rules)
    // console.log(my_json)

    var controls = this.state.rules.map((rule,index)=> 
      <CountryFormRow key={index} id={rule.id} url={rule.url} matches={rule.matches} what={rule.what} onUpdate={this.handleChange} />
    )

    var buttons =
      <div className="form-group row">
        <div className="col-sm-12">
          <div className="pull-right">
            {this.state.rules.length > 0 &&
            <a onClick={this.handleDelete} className="btn btn-white btn-sm">
              Remove
            </a>
            }
            <a onClick={this.handleAdd} className="btn btn-white btn-sm">
              + Add Another
            </a>
          </div>
        </div>
      </div>

    var json_state =
      <div>
        {JSON.stringify(this.state.rules)}
      </div>

    return([controls, buttons, json_state])

  }
}
export default CountryForm;

子对象:

import React, { Component } from 'react';

class CountryFormRow extends React.Component {
  constructor(props) {
    super(props)
    this.state = {url: props.url, matches: props.matches, what: props.what}
    this.handleInputChange = this.handleInputChange.bind(this)
  }

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

  render() {
    return (
      <div className="geo-field">
        <div className="form-group row">
          <input id="link_dd_0_what" name="link[dd_0_what]" type="hidden" value="this.props.country"/>
          <label className="col-sm-2 col-form-label">Country</label>
          <div className="col-sm-10">
            <select onChange={this.handleInputChange} className="form-control m-b" name="matches" defaultValue={this.props.matches}><option value=""></option><option value="AF">Afghanistan</option><option value="AL">Albania</option><option value="DZ">Algeria</option><option value="AS">American Samoa</option></select>
          </div>
        </div>
        <div className="form-group row">
          <label className="col-sm-2 col-form-label">Destination</label>
          <div className="col-sm-10">
            <input onChange={this.handleInputChange} className="form-control" name="url" placeholder="https://www.example.com" type="text" defaultValue={this.props.url}/>
          </div>
        </div>
      </div>
      )
  }
}

export default CountryFormRow

2 个答案:

答案 0 :(得分:2)

您可以将状态保留在父组件中,而不是将状态保留在CountryFieldRow中并尝试将其同步到父组件状态,而是将状态更改功能传递给CountryFieldRow

示例

class App extends React.Component {
  state = {
    rows: [
      {
        country: "Andorra",
        destination: "www.alpha.com"
      }
    ]
  };

  addRow = () => {
    this.setState(prevState => ({
      rows: [...prevState.rows, { country: "", destination: "" }]
    }));
  };

  onChangeCountry = (country, index) => {
    this.setState(prevState => {
      const rows = [...prevState.rows];
      rows[index] = { ...rows[index], country };
      return { rows };
    });
  };

  onChangeDestination = (destination, index) => {
    this.setState(prevState => {
      const rows = [...prevState.rows];
      rows[index] = { ...rows[index], destination };
      return { rows };
    });
  };

  render() {
    return (
      <div>
        {this.state.rows.map((row, i) => (
          <CountryFieldRow
            country={row.country}
            onChangeCountry={e => this.onChangeCountry(e.target.value, i)}
            destination={row.destination}
            onChangeDestination={e =>
              this.onChangeDestination(e.target.value, i)
            }
          />
        ))}
        <button onClick={this.addRow}> Add another </button>
      </div>
    );
  }
}

function CountryFieldRow(props) {
  return (
    <div>
      <input value={props.country} onChange={props.onChangeCountry} />
      <input value={props.destination} onChange={props.onChangeDestination} />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>

答案 1 :(得分:0)

您需要管理上级组件中的状态。

您应该将对保持在较高组件的状态,并将其传递给CountyFieldRow元素。

这样,您就可以拥有一种状态并包含所需的所有信息,并且可以使用它来更新JSON。

要从组件更新父状态,您需要向组件传递onUpdate函数,该函数将更新父组件状态的右侧。

这足够清楚吗?如果没有,请附加一些代码示例,我将使其更加清晰