1
votes

(React) Setstate conditionnel de composant dynamique

J'essaie de créer un composant dynamique qui correspond à l'index de données avec le paramètre d'URL blogID que j'obtiens avec le avec le routeur.

Ici, j'ai les paramètres du routeur et j'envoie les accessoires au composant

   render(){                  
        const { params:{ blogId, blogTitle } } = this.props.match;  

// so i map here to get the index and set the conditional to set the new state but I don't know where or how exactly        

        this.props.blogData.map((val, idx) => ( 
            idx == blogId ? 
                this.setState({blogData:val }) : null                               
        ))
        return (                          
          <div>              


           <BlogView title={this.state.blogData.title} />


          </div>
        )  
    } 

puis sur le composant, je règle l'état initial et j'essaye de rendre les données qui correspondent à l'index des données, mais j'obtiens une erreur de composant appelant à plusieurs reprises setstate et des boucles infinies.

constructor(props){
        super(props);
        this.state = {
            blogId:'',
            blogTitle:'',
            blogData:[]
        }            
    }   
<Route path='/blog/:blogId/:blogTitle' render={() => <BlogPost blogData={this.state.blogData} /> }  />     


0 commentaires

5 Réponses :


0
votes

Si vous appelez setState dans le rendu comme ceci, vous provoquerez des boucles infinies.

Vous n'avez pas besoin de setState une fois que vous avez trouvé le blog , utilisez simplement son titre dans BlogView après un find:

render() {                  
    const { params:{ blogId, blogTitle } } = this.props.match;        

    const blog = this.props.blogData.find((val, idx) => idx === blogId);
    return (                          
        <div>
            <BlogView title={blog.title} />
        </div>
        );  
} 


0 commentaires

2
votes

La raison pour laquelle vous obtenez une boucle infinie qui appelle un setState dans votre méthode de rendu, ce qui provoque un re-rendu, ce qui provoque un setState, qui provoque un re-rendu ... etc.

Essayez de retirer cette partie de la méthode de rendu.

this.props.blogData.map ((val, idx) => ( idx == blogId? this.setState ({blogData: val}): null))


0 commentaires

1
votes

Vous ne devriez pas définirState dans la fonction render (), la raison en est que lorsque vous définissez state, compoennt doit effectuer un nouveau rendu pour montrer à l'utilisateur les données mises à jour, puis le restituer encore et encore, à la place, faites-le dans componentDidMount lifeCycle méthode pour qu’elle ne s’exécute qu’une seule fois

componentDidMount() {
  const { params:{ blogId, blogTitle } } = this.props.match;  
  this.props.blogData.map((val, idx) => ( 
    idx == blogId ? 
    this.setState({blogData:val }) : null                               
  ))
}


0 commentaires

0
votes

Ajoutez un bloc conditionnel avant d'appeler l'état défini dans le rendu. si les deux valeurs sont identiques, n'appelez pas l'état défini.

   render(){                  
        const { params:{ blogId, blogTitle } } = this.props.match;  

// so i map here to get the index and set the conditional to set the new state but I don't know where or how exactly        

        this.props.blogData.map((val, idx) => ( 
            (idx == blogId && val != this.state.blogData) ? 
                this.setState({blogData:val }) : null                               
        ))
        return (                          
          <div>              


           <BlogView title={this.state.blogData.title} />


          </div>
        )  
    } 


0 commentaires

0
votes

Oui je l'ai finalement fait,

J'ai défini l'état sur le componentDidMount ()

const blogger =  this.props.blogData.map((val, idx) => (             
            idx == this.state.blogId ?
                <BlogView 
                    title={val.title}
                    body={parse(val.body)}
                    img={val.thumb}
                />
                : null            
        )) 

et la comparaison sur le rendu et ça a fonctionné parfaitement

componentDidMount(){                        
  const { params:{ blogId, blogTitle } } = this.props.match;           
  this.setState({blogId, blogTitle});
} 


0 commentaires