web-dev-qa-db-fra.com

composantWillReceiveProps ne tire pas

Dans mes autres classes, composantWillReceiveProps fonctionnait bien, mais pour une raison quelconque, il ne se déclenche pas ici.

ItemView.jsx

class ItemView extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            name: null, 
            rating: null, 
            sector: null, 
            location: null, 
            description: null, 
            image: "blank.png",
            show: false
       };
    }

    ...

    componentWillReceiveProps(nextProps) {

        if(!nextProps.companyToRender) {
            this.setState({
                name: null, 
                rating: null, 
                sector: null, 
                location: null, 
                description: null, 
                image: "blank.png",
                show: false
            });
       }
       else {
           var companyToRender = nextProps.companyToRender;

           this.setState({
               name: companyToRender.name, 
               rating: companyToRender.rating, 
               sector: companyToRender.sector, 
               location: companyToRender.location, 
               description: companyToRender.description, 
               image: companyToRender.image,
               show: true
           });
    }

    ...

    render () {
       return(
        <div>
         ...
        <CommentBox show={this.state.show} companyToRender={this.state.name}/>
         ...
        </div>
       );

    }
}

CommentBox.jsx

class CommentBox extends React.Component {
    constructor(props) {
        super(props);
        this.state = {companyToRender: null};
    }

    componentWillReceiveProps(nextProps) {
        this.setState({companyToRender: nextProps.companyToRender});
    }

    ...
}

Le prop transmis à itemView est nul si rien ne doit être passé ou le tableau que ItemView lui attribue.

composantWillReceiveProps () ne se déclenche que lorsque les attributs de l'état deviennent nuls, mais pas lorsqu'il est défini. ((null -> entry) ne fonctionne pas mais (entry -> null) fonctionne).

Est-ce que je manque quelque chose? Merci!

-- modifier:

(null -> entry) met à jour l'état, mais n'appelle pas les journaux ni aucun autre composant ComponentWillRecieveProps (). (Mais l'entrée -> null le fait.)

Journaux pour null -> entrée

Logs for entry -> null

24
Carlo Pascual

Après un débogage très pénible, j'ai découvert que le problème était que ItemView était appelé dans un modal (react-bootstrap) qui, pour une raison quelconque, ne prend pas en charge ComponentWillReceiveProps (). J'ai fini par résoudre le problème en refacturant le code. Merci les gars!

20
Carlo Pascual

Si quelqu'un d'autre a un problème avec ça ...

componentWillReceiveProps sera pas appelé si vous recevez le exact même comme avant. Ce que vous pouvez faire pour contourner ce problème consiste à ajouter un accessoire factice qui est itéré chaque fois que vous souhaitez envoyer le même accessoire au composant au cas où ce composant se réinitialise de manière interne.

click() {
    this.setState({counter: ++this.state.counter, unchangingProp:true})
}
<Component unchangingProp={this.state.unChangingProp} counter={this.state.counter}/>

De cette façon, componentWillRecieveProps sera déclenché à chaque fois.

13
Leon

Dans mon cas, mon composant était recréé à chaque rendu, il a donc fallu que je mette ma logique dans le constructeur. Je sais que ce n’est pas idéal, mais c’était un composant simple et plus facile à résoudre que d’essayer de résoudre le problème qui entraînait la recréation du composant à chaque fois.

6
Scott Jungwirth

j'ai aussi eu le même problème. si quelqu'un tape dans une URL directe, le composant recevra les accessoires ne sera pas déclenché. Je devais aussi refactoriser mon code pour que tout fonctionne.

Les modifications que j'ai apportées étaient dans mon index initial.tsx comme ayant (par exemple, le routeur comme élément externe):

render( 
<Router history={hashHistory} >
{routes}
</Router>
, document.getElementById('root'));

ma route par défaut était ma page app.tsx avec une structure comme suit: render () {

return (
 <Provider store={store}>
   <div id="appContainer">
           {this.props.children}
   </div>
 </Provider>
);

}

2
Jay