开发者问题收集

React-places-autocomplete——使用自动完成时如何设置三个输入的状态?

2017-10-01
2231

每个 PlacesAutoComplete 组件都需要有 inputprops,它将具有指向 handleChange 的 onChange,但 handleChange 仅为 address1 设置状态,因为当每个单独的输入都有地址时,我不确定如何更新每个单独地址的状态。所以在我的示例中,我有三个 PlacesAutoComplete 组件,我希望第一个为 address1 设置状态,第二个为 address2 设置状态,第三个为 address3 设置状态。我该如何更改代码,以便每个单独的 PlacesAutoComplete 为相应的 address1、address2 或 address3 设置状态?

class AutoCompleteForm extends React.Component {
 constructor() {
  super()
  this.state = {
   address1: '',
   address2: '',
   address3: ''
 }
}


handleChange = (address) => {
  this.setState({
      address1: address, 
    })
  }

render() {
  const inputProps = {
    value: this.state.address,
    onChange: this.handleChange,
    placeholder: "Enter a location"
  }

  return (
    <form onSubmit={this.handleFormSubmit}>
      <PlacesAutocomplete inputProps={inputProps} />
      <PlacesAutocomplete inputProps={inputProps} />
      <PlacesAutocomplete inputProps={inputProps} />
      <button type="submit">Find Midpoint</button>
    </form>
  )
}
} 

export default AutoCompleteForm
2个回答

一种方法是编写 3 个不同的函数来处理所有 3 个不同的 autocomplete ,如

handleChange1 = (address) => {
  this.setState({
    address1: address, 
  })
 }

handleChange2 = (address) => {
  this.setState({
    address3: address, 
  })
 }

但是,上面的方法会增加更多代码并重复相同的逻辑。如果您可以使用某种模式,那么我们可以使用单个函数来执行逻辑。 假设您的状态将是 address1address2address3

现在让我们编写一个接受两个参数的函数。一个是实际的自动完成地址,另一个是州名称。

handleAddressChange = (address, stateName) => {
  this.setState({
   [stateName]: address, 
  });
}

现在让我们修改您的渲染以发送州名称

render() {
  const inputProps = {
    value: this.state.address,
    placeholder: "Enter a location"
  }

  return (
    <form onSubmit={this.handleFormSubmit}>
      <PlacesAutocomplete inputProps={inputProps} onChange={(address) => {this.handleAddressChange(address, 'address1')}} />
      <PlacesAutocomplete inputProps={inputProps} onChange={(address) => {this.handleAddressChange(address, 'address2')}} />
      <PlacesAutocomplete inputProps={inputProps} onChange={(address) => {this.handleAddressChange(address, 'address3')}} />
      <button type="submit">Find Midpoint</button>
    </form>
  )
}

现在,这将在调用 onChange 时设置相应的状态。

Panther
2017-10-02

我也遇到过类似的情况。

我该如何解决?请按照下面列出的步骤操作:

0) 像这样声明您的构造函数:

constructor(props) {
  super(props);
  this.state = {
    latLngObj: {}
  }
}

1) 在 render() 之外声明以下函数 {

handleAddressChange = (address, stateName) => {
  this.setState({
    [stateName]: address,
  });
}

2) 我有一个预先选择位置的循环,因此我像这样使用它:

<Fragment>
            {
              Object.keys(this.props.selectedLocations).map((i) => {
                return(
                  <div key={i} style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
                    <label className="spacer-right">{this.state.selectedLocations[i].label}: </label>
                    <PlacesAutocomplete inputProps={{value: this.state[`address_${this.props.selectedLocations[i].label.toLowerCase()}`], onChange: (address) => {this.handleAddressChange(address, `address_${this.props.selectedLocations[i].label.toLowerCase()}`)}}} />
                  </div>
                )
              })
            }
          </Fragment>

3) 然后单击另一个按钮(在我的情况下是“完成”按钮),我们可以进行地理编码以获取上面所有指定位置的经纬度:

let tempLatLngObj = this.state.latLngObj;
Object.keys(this.state).map((key, index) => {
  if(key.startsWith("address_")) {
    geocodeByAddress(this.state[key])
      .then(results => getLatLng(results[0]))
      .then(latLng => {
        tempLatLngObj[key] = latLng;
        this.setState({ latLngObj: tempLatLngObj }, () => {
          if(index === Object.keys(this.state).length-1) {
            // Your AXIOS API call or whatever operation with the final collection of data stored in latLngObj
          }
        })
      })
      .catch(error => console.error('Error', error))
  }
})

我可能迟到了这个答案,但希望这个答案将来能帮助遇到同样问题的人。

谢谢,祝一切顺利,

Rohit Paniker

rohitpaniker
2018-03-23