2017-12-29 23 views
0

양식을 작성하려고합니다. 양식의 끝에서 위치를 선택할 수 있습니다. 나는 이것을 places-autocomplete으로 사용하고 있습니다. Locationpicker는 Form-View 구성 요소의 하위 항목입니다. 좌표의 상태는 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> 
    ); 
    } 
} 

내 부모 구성 요소에서 위도와 LNG를 사용하고 싶습니다,하지만 난 내 부모에게 handleSelect 기능을 추가 할 수 없습니다. 부모 컴포넌트에 lat 및 lng를 보내려면 어떻게해야합니까?

당신은 부모 상태 address를 업데이트하는 아이에게 부모에서 함수를 전달할 수
+1

은 당신이 할 수있는 구성 요소를 결정해야한다고 생각 ['표상 어느 하나의 컨테이너 component' (https://medium.com/@dan_abramov/smart-and-dumb - 구성 요소 - 7ca2f9a7c7d0). 나는 당신이 구현하려고 시도하는 그런 접근법을 좋아하지 않는다. 당신은 하위 컴포넌트들 ['here'] (https://stackoverflow.com/questions/22639534/pass-props-to-parent-component-in-react-js)에 소품과 핸들러를 전달하는 부모 컴포넌트를 가질 수 있습니다. 그런 일들을 어떻게 처리 할 수 ​​있는지. 내가 아는 한 그것은 –

+0

@TheReason 내 자녀와 부모 모두 컨테이너 구성 요소가 될 것이므로 이것이 최선의 방법은 아닐 것이라고 제안한 방식으로 리팩토링 될 수 있습니다. 어떻게 할 건데? –

+0

['this']와 비슷한 것 (https://jsfiddle.net/69z2wepo/96647/). 이 경우에 당신은 Presentational 컴포넌트로서'LocationPicker'를 가지고 있고 컨테이너로서 ParentComponent를 가지고 있습니다. 나는 앱 상태 관리를 위해'redux' 나'mobx'와 같은 라이브러리를 사용하고 있는지 잘 모르겠습니다. 그리고이 모든 상태는 '희박 국가'에서 올 수 있습니다. –

답변

0

:

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> 
     ) 
    } 
} 

또는, 부모 (컨테이너) 구성 요소에 주소 상태의 모든 이동하고 아래로 통과 할 수 소품과 하위 구성 요소에 대한 모든 :

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> 
     ) 
    } 
}