Je suis assez nouveau chez React. J'ai un composant principal et un composant enfant contenant une table. Sur componentDidmount, j'envoie une demande à l'API et je reçois des données que je rend dans le tableau. C'est ma première mise à jour du composant enfant. Ensuite, je peux ajouter et supprimer des lignes du tableau et après l'un de ces événements, mon application affiche une notification (via componentDidUpdate). Malheureusement, une notification apparaît après avoir reçu des données initiales, ce qui n'est pas ce que je veux.

var App = React.createClass({
getInitialState: function(){
    return {
        users:[],
        display: "none",
        currentId : 3,
    }
},
componentDidMount: function() {
    var that = this;
    this.serverRequest = 
      axios
        .get(API_URL + "/users")
        .then(function(result) {  
            that.setState({
            users: result.data
          });
        });
},
render: function(){
    return (
        <div className="container-fluid">
            <NotificationSystem ref="notificationSystem" />
            <div>
                <button className="btn btn-info" onClick={this.handleClick}>Add user</button>
            </div>  
            {this.manageForm()}
            <UsersTable data={this.state.users} onDeleteUser={this.deleteUser} addNotification={this._addNotification} />

        </div>
    );
}
});

var UsersTable = React.createClass({
renderRows: function() {
    var that = this;
    var rows;
    if(this.props.data.length !== 0){
        rows = this.props.data.map(function(row){
        return <UsersRow key={row.id} data={row} onDeleteUser={that.props.onDeleteUser} />
        })
    } else {
        rows = <UsersPlaceholder />;
    }
    return rows;
},
shouldComponentUpdate: function(nextProps, nextState) {
    return nextProps.data !== this.props.data;
},

componentDidUpdate: function (prevProps, prevState) {
    this.props.data.length > prevProps.data.length ? this.props.addNotification('User was added','success') : this.props.addNotification('User was deleted','error');
},

render: function(){

    return (
            <table className="table">   
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>e-mail</th>
                        <th>del</th>
                    </tr>
                </thead>
                <tbody> 
                    {this.renderRows()}
                </tbody>    
            </table>
    ); 
}

});

Existe-t-il une possibilité de "capturer" la première mise à jour du composant de table afin de ne plus afficher la notification?

0
magnat 9 août 2016 à 12:26

3 réponses

Meilleure réponse

Utilisez-le comme le code ci-dessous, cela fonctionnera pour moi

var App = React.createClass({
getInitialState: function(){
    return {
        users:[],
        display: "none",
        currentId : 3,
        callonUpdate : true,
    }
},
deleteUser:function( id ){
        var data = [{id:2,name:"Ahmad ali"}];
        this.setState({
            users: data
          });
},
toggleUpdate:function() {
            console.log("update");
        this.setState({
            callonUpdate: true,
          });
},

componentDidMount: function() {
        var data = [{id:1,name:"shahid ahmad"},{id:2,name:"Ahmad ali"}];
    this.setState({
            users: data,
            callonUpdate : false
          });
},
render: function(){
    return (
        <div className="container-fluid">
            <UsersTable data={this.state.users} checkonCall = {this.state.callonUpdate} togglecallonUpdate = {this.toggleUpdate} onDeleteUser={this.deleteUser} />

        </div>
    );
  }
 });



var UsersTable = React.createClass({
delete : function( id ) {
        this.props.onDeleteUser(id);
},
renderRows: function() {
    var that = this;
    var rows;
    if(this.props.data.length !== 0){
        rows = this.props.data.map(function(row){
        return <tr>
                    <td>{row.id}</td>
                    <td> {row.name} </td>
              <td onClick={this.delete.bind(this,row.id)}>Delete </td>
              </tr>
        },this)
    } 
    return rows;
},

shouldComponentUpdate: function(nextProps, nextState) {
    return nextProps.data !== this.props.data;
},

componentDidUpdate: function (prevProps, prevState) {
    console.log(this.props.checkonCall);
    if(this.props.checkonCall) {
    this.props.data.length > prevProps.data.length ? console.log('User was added') : console.log('User was deleted');
    }

    this.props.togglecallonUpdate();

},

render: function(){

    return (
            <table className="table">   
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                    </tr>
                </thead>
                <tbody> 
                    {this.renderRows()}
                </tbody>    
            </table>
    ); 
}

});
ReactDOM.render(
 <App  />,
 document.getElementById('container')
);
1
Shahid Ahmad 9 août 2016 à 12:11

Si je comprends bien (vous ne voulez pas que la population initiale ajoute une notification), vous pouvez vérifier que les accessoires précédents n'étaient pas vides dans votre méthode componentDidUpdate:

componentDidUpdate: function (prevProps, prevState) {
    this.props.data.length > prevProps.data.length && prevProps.data.length > 0 ? this.props.addNotification('User was added','success') : this.props.addNotification('User was deleted','error');
}

Cela ne traitera pas les cas où tous les utilisateurs sont supprimés et un autre est ensuite ajouté. Pour ce faire, vous pouvez définir une propriété dans l'état en cas de succès ajax, la transmettre au composant enfant et la mettre à jour dans l'état parent lors d'une mise à jour de l'enfant.

1
Lee 9 août 2016 à 09:45

En fait, vous comprenez mal le concept selon la documentation officielle de React Js.

  • componentDidMount () Appelé une fois, uniquement sur le client (pas sur le serveur), immédiatement après le rendu initial. À ce stade du cycle de vie, vous pouvez accéder à toutes les références de vos enfants (par exemple, pour accéder à la représentation DOM sous-jacente). La méthode componentDidMount () des composants enfants est invoquée avant celle des composants parents. Vous allez charger vos données initiales dans componentDidMount qui appellent réellement après le rendu de votre composant pour charger vos données initiales, vous devez utiliser componentWillMount ()

ComponentWillMount sera immédiatement avant le rendu initial. Si vous appelez setState dans cette méthode, render () verra l'état mis à jour et ne sera exécuté qu'une seule fois malgré le changement d'état.

Changez componentDidMount avec componentWillMount pour charger vos données initiales cela résoudra votre problème

0
Shahid Ahmad 9 août 2016 à 09:47