2017-09-12 3 views
1

Je tente de mettre à jour le composant center du composant enfant BaseMap via le composant parent. Même si l'état des composants parents est mis à jour (et que j'ai pu lire les nouvelles propriétés mises à jour dans le console.log), il n'est pas transmis aux propriétés enfant.L'état de l'enfant React ne se met pas à jour après la mise à jour du composant parent

La dernière chose que j'ai essayé a été la méthode componentWillReceiveProps. Ça ne marche toujours pas.

Ceci est mon code:

const google = window.google; 
let geocoder = new google.maps.Geocoder(); 

class App extends Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     avatar: '', 
     username: 'someUse03', 
     realName: '', 
     location: '', 
     followers: '', 
     following: '', 
     repos: '', 
     address: '', 
     } 
    } 

    render() { 
    return (
     <div> 
     <SearchBox fetchUser={this.fetchUser.bind(this)}/> 
     <Card data={this.state} /> 
     <BaseMap /> 
     </div> 
    ); 
    } 

    fetchApi(url) { 
    fetch(url) 
     .then((res) => res.json()) 
     .then((data) => { 
     this.setState({ 
      avatar: data.avatar_url, 
      username: data.login, 
      realName: data.name, 
      location: data.location, 
      followers: data.followers, 
      following: data.following, 
      repos: data.public_repos, 
      address: geocoder.geocode({'address': data.location}, function(results, status) { 
      if (status == 'OK') { 
       var coords = []; 
       var results = results.map((i) => { 
       i.geometry.location = i.geometry.location 
          .toString() 
          .replace(/[()]/g, '') 
          .split(', '); 
       coords.push(i.geometry.location[0], i.geometry.location[1]); 
       results = coords.map((i) => { 
        return parseInt(i, 10) 
       }); 
       return results; 
       }); 
      } else { 
       alert('Geocoding was not successfull because ' + status) 
      } 
      }) 
     }) 
     }); 
    } 

    fetchUser(username) { 
    let url = `https://api.github.com/users/${username}`; 

    this.fetchApi(url); 
    } 

    componentDidMount() { 
    let url = `https://api.github.com/users/${this.state.username}`; 

    this.fetchApi(url); 
    } 

} 

export default App; 

Ceci est le composant enfant:

BaseMap extends React.Component { 
     constructor(props) { 
      super(props); 
      this.state = { 
       center: [41, 21], 
      } 
     } 

     componentWillReceiveProps(nextProps) { 
      this.setState({ center: nextProps.address}); 
     } 

     render() { 
      return (
       <Col md={10} mdPull={1}> 
        <div className="map"> 
         <GoogleMap 
         bootstrapURLKeys={'AIzaSyBhzwgQ3EfoIRYT70fbjrWASQVwO63MKu4'} 
         center={this.state.center} 
         zoom={11}> 
         </GoogleMap> 
        </div> 
       </Col> 
      ); 
     } 
    } 

Répondre

2

Vous récupérez dans la méthode de rendu. c'est un grand NON NON.
faire au lieu que dans le componentDidMountlife cycle method

Une autre chose qui peut ou non être lié à votre problème, les tableaux sont les types de référence, cela signifie que si vous les muter, ils pointent toujours à la même ref dans la mémoire. cela pourrait être problématique pour le Reconciliation and diff algorithm of react pour déterminer si l'état a effectivement changé.
lorsque vous voulez changer ou retourner un nouveau tableau vous pouvez simplement utiliser le ES6 spread operator:

const nextArray = [...nextProps.address] 
this.setState({ center: nextArray }); 

EDIT
Ok j'ai oublié de mentionner la partie la plus importante ici :)
Vous n'êtes pas de passage tout les accessoires à <BaseMap /> de sorte que vous n'obtiendrez pas de données utiles dans componentWillReceiveProps.

+0

Vous pointez sur la ligne ''? – IsaaK08

+1

Oui. Le modèle général pour les éléments qui doivent être récupérés lors du chargement de la page consiste à déclencher une action à partir de componentWillMount, par exemple fetchUser. Ceci à son tour définira alors l'état quand les données ont été retreived. Si c'est asynchrone, regardez les sagas ou les thunks. Les thunks sont plus faciles à apprendre, mais les sagas sont sans doute plus utilisées, du moins en ce moment. –

+1

@ WillyG vous voulez dire 'componentDidMount'. Vous ne devriez jamais chercher sur 'componentWillMount' ou dans le' constructor'. https://facebook.github.io/react/docs/react-component.html#componentwillmount –