从子组件

时间:2017-12-29 14:46:49

标签: reactjs

我正在尝试构建一个表单,您可以在表单末尾选择一个位置。我正在使用places-autocomplete。 Locationpicker是Form-View Component的子代。当我在handleSelect()中选择位置时设置坐标的状态,但是如果我想将它添加到父级中的表单数据中,我就无法访问它。

子组件

class LocationPicker extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      address: "San Francisco, CA",
      lat: "",
      lng: ""
    };
    this.handleSelect = this.handleSelect.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }
  handleSelect(address) {
    this.setState({
      address
    });
    geocodeByAddress(this.state.address)
      .then(results => getLatLng(results[0]))
      .then(latLng => this.setState({ lat: latLng.lat, lng: latLng.lng }))
      .catch(error => console.error("Error", error));
  }

  handleChange(address) {
    this.setState({
      address,
      geocodeResults: null
    });
  }

  render() {
    const inputProps = {
      value: this.state.address,
      type: "text",
      onChange: this.handleChange,
    };

    return (
      <div>
        <PlacesAutocomplete
          onSelect={this.handleSelect}
          onEnterKeyDown={this.handleSelect}
          inputProps={inputProps}
        />
        <p>{this.state.lat}</p>
        <p>{this.state.lng}</p>
      </div>
    );
  }
}

现在我想在我的父组件中使用lat和lng,但我不想将handleSelect函数添加到我的父组件中。 如何将lat和lng发送到我的父组件?

1 个答案:

答案 0 :(得分:1)

您可以将一个函数从父级传递给在父级状态下更新address的子级:

class LocationPicker extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            address: props.address || "San Francisco, CA",
            lat: "",
            lng: ""
        };
        this.handleSelect = this.handleSelect.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }
    handleSelect(address) {
        this.props.updateAddress(address);
        geocodeByAddress(address)
            .then(results => getLatLng(results[0]))
            .then(latLng => this.setState({ lat: latLng.lat, lng: latLng.lng }))
            .catch(error => console.error("Error", error));
    }

    handleChange(address) {
        this.props.updateAddress(address);
        this.setState({
            geocodeResults: null
        });
    }

    componentWillReceiveProps(prevProps, nextProps) {
        if(prevProps.address !== nextProps.address){
            this.setState({
                address: nextProps.address
            });
        }
    }

    render() {
        const inputProps = {
            value: this.state.address,
            type: "text",
            onChange: this.handleChange,
        };

        return (
            <div>
                <PlacesAutocomplete
                    onSelect={this.handleSelect}
                    onEnterKeyDown={this.handleSelect}
                    inputProps={inputProps}
                />
                <p>{this.state.lat}</p>
                <p>{this.state.lng}</p>
            </div>
        );
    }
}

export default class Parent extends Component {
    state = {
        address: ''
    };
    updateAddress = address => {
        this.setState({
            address
        });
    }
    render() {
        return (
            <div>
                <LocationPicker address={address} />
            </div>
        )
    }
}

或者,您可以将所有地址状态移动到父(容器)组件,并将所有内容传递给子组件作为props:

class LocationPicker extends React.Component {
    render() {
        const inputProps = {
            value: this.props.address,
            type: "text",
            onChange: this.props.handleChange,
        };
        return (
            <div>
                <PlacesAutocomplete
                    onSelect={this.handleSelect}
                    onEnterKeyDown={this.handleSelect}
                    inputProps={inputProps}
                />
                <p>{this.props.lat}</p>
                <p>{this.props.lng}</p>
            </div>
        );
    }
}

export default class Parent extends Component {
    state = {
        address: '',
        geocodeResults: null,
        lat: '',
        lng: ''
    }
    handleSelect = address => {
        this.setState({
            address
        });
        geocodeByAddress(this.state.address)
            .then(results => getLatLng(results[0]))
            .then(latLng => this.setState({ lat: latLng.lat, lng: latLng.lng }))
            .catch(error => console.error("Error", error));
    }
    handleChange = address => {
        this.setState({
            address,
            geocodeResults: null
        });
    }
    render() {
        return (
            <div>
                <LocationPicker address={this.state.address} handleSelect={this.handleSelect}/>
            </div>
        )
    }
}