Je suis assez nouveau pour réagir et j'ai démonté une application Web et remplacé des pièces par des composants de réaction. Je travaille maintenant sur un composant qui contient quelques-uns des différents composants que j'ai créés.
Dans le nouveau composant, je fais un appel API dans la fonction componentDidMount et crée les composants enfants. À première vue, tout semble parfait, mais lorsque nous modifions l'état de l'un des composants enfants, puis que nous modifions le composant parent, les composants enfants réinitialisent leur état à ce qu'ils étaient avant les modifications.
I comprendre ce qui se passe que l'état n'est pas transmis au parent, mais je ne suis pas sûr s'il y a une conception pour cela qui me manque ou si je dois passer à un magasin redux pour que cela fonctionne p >
class Frame extends Component{
constructor(props){
super(props);
this.state = {
tab: "tab1",
tab1: null,
tab2: null,
}
}
componentDidMount() {
let data = this.props.service.getData();
let tab1 = (<Tab1 {...data} />);
let tab2 = (<Tab2 {...data} />);
this.setState({tab1:tab1, tab2:tab2});
}
render(){
if (!this.state.tab1 || !this.state.tab2){
return (<div>Loading</div>)
}
return (
<ul>
<li onClick={()=>{this.setState({tab:"tab1"})}}></li>
<li onClick={()=>{this.setState({tab:"tab2"})}}></li>
<ul>
<div>
{this.state.tab === "tab1" &&
this.state.tab1
}
{this.state.tab === "tab2" &&
this.state.tab2
}
</div>
)
}
}
3 Réponses :
Écrivez un gestionnaire de clics qui définit l'état et appelez-le onClick plutôt que de définir l'état directement dans le rendu.
componentDidMount ne fonctionne qu'une seule fois. class Frame extends Component {
constructor(props) {
super(props);
this.state = {
tab: 'tab1',
data: null,
};
}
componentDidMount() {
let data = this.props.service.getData();
if (data) {
this.setState({ data });
}
}
render() {
if (this.state.data) {
return <div>Loading</div>;
}
return (
<div>
<ul>
<li
onClick={() => {
this.setState({ tab: 'tab1' });
}}
/>
<li
onClick={() => {
this.setState({ tab: 'tab2' });
}}
/>
</ul>
<div>
{this.state.tab === 'tab1' && <Tab {...this.state.data} />}
{this.state.tab === 'tab2' && <Tab {...this.state.data} />}
</div>
</div>
);
}
}
axnyff, le commentaire était la solution. Le if instancierait à nouveau l'objet dans le rendu puisqu'il n'y était pas auparavant. Si j'ai utilisé une classe css pour les masquer, elles ne seront instanciées qu'une seule fois puisque
class Frame extends Component{
constructor(props){
super(props);
this.state = {
tab: "tab1",
tab1: null,
tab2: null,
}
}
componentDidMount() {
let data = this.props.service.getData();
let tab1 = (<Tab1 {...data} />);
let tab2 = (<Tab2 {...data} />);
this.setState({tab1:tab1, tab2:tab2});
}
render(){
if (!this.state.tab1 || !this.state.tab2){
return (<div>Loading</div>)
}
return (
<ul>
<li onClick={()=>{this.setState({tab:"tab1"})}}></li>
<li onClick={()=>{this.setState({tab:"tab2"})}}></li>
<ul>
<div>
<div class=> {this.state.tab !== "tab1" && "hidden"}>
{this.state.tab1}
</div>
<div class=> {this.state.tab !== "tab2" && "hidden"}>
{this.state.tab2}
</div>
</div>
)
}
}
Vous démontez le composant enfant à chaque changement d'onglet, de sorte que leur état local est perdu. Vous devez soit toujours rendre le composant enfant (peut-être simplement le masquer), soit conserver son état dans le composant parent. Autre point, il est probablement préférable de conserver simplement les données dans votre composant au lieu du composant rendu
Cela a fonctionné. Je viens de déplacer la logique if pour les masquer à l'aide d'une classe css. afin qu'ils ne soient rendus qu'une seule fois car la logique if n'interrompt pas le rendu des autres onglets. Merci