मुझे उम्मीद थी कि यह टॉगल काम करेगा लेकिन किसी तरह घटक <A/> के निर्माता को केवल एक बार बुलाया जाता है। https://codesandbox.io/s/jvr720mz75

import React, { Component } from "react";
import ReactDOM from "react-dom";

class App extends Component {
  state = { toggle: false };
  render() {
    const { toggle } = this.state;
    return (
      <div>
        {toggle ? <A prop={"A"} /> : <A prop={"B"} />}
        <button onClick={() => this.setState({ toggle: !toggle })}>
          toggle
        </button>
      </div>
    );
  }
}

class A extends Component {
  constructor(props) {
    super(props);
    console.log("INIT");
    this.state = { content: props.prop };
  }

  render() {
    const { content } = this.state;
    return <div>{content}</div>;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));

मुझे https://codesandbox.io/s/0qmnjow1jw समाधान पहले ही मिल गया है।

<div style={{ display: toggle ? "none" : "block" }}>
  <A prop={"A"} />
</div>
<div style={{ display: toggle ? "block" : "none" }}>
  <A prop={"B"} />
</div>

मैं समझना चाहता हूं कि उपरोक्त कोड काम क्यों नहीं कर रहा है

4
Thomas Sojka 19 सितंबर 2018, 11:03

3 जवाब

सबसे बढ़िया उत्तर

प्रतिक्रिया में यदि आप एक ही घटक को कई बार प्रस्तुत करना चाहते हैं और उन्हें अलग मानते हैं तो आपको उन्हें एक अद्वितीय key प्रदान करने की आवश्यकता है। नीचे दिए गए कोड का प्रयास करें।

{toggle ? <A key="A" prop={"A"} /> : <A key="B" prop={"B"} />}
3
Raghav Garg 19 सितंबर 2018, 11:14

चूंकि वह टर्नरी स्टेटमेंट किसी भी मामले में <A> घटक में परिणाम प्रस्तुत करता है, जब <App> की स्थिति अपडेट और toggle बदलती है, तो रिएक्ट देखता है कि अभी भी एक <A> है पहले की तरह ही, लेकिन एक अलग prop प्रोप के साथ। जब रिएक्ट पुन: प्रस्तुत करता है तो यह यथासंभव कम परिवर्तन करके ऐसा करता है। इसलिए चूंकि यह एक ही स्थान पर तत्व का एक ही वर्ग है, इसलिए जब toggle बदलता है, तो रिएक्ट को एक नया तत्व बनाने की आवश्यकता नहीं होती है, केवल उस <A> तत्व के प्रॉप्स को अपडेट करें।

अनिवार्य रूप से, रेखा

{toggle ? <A prop="A"/> : <A prop="B"/> }

के बराबर है

<A prop={ toggle ? "A" : "B" }/>

जो शायद अधिक स्पष्ट रूप से एक नया <A> घटक बनाने की आवश्यकता नहीं है, केवल मौजूदा को अपडेट करें।

तब समस्या यह हो जाती है कि आप कंस्ट्रक्टर में props.prop का उपयोग करके <A> का state.content सेट करते हैं, इसलिए state.content कभी भी अपडेट नहीं होता है। इसे ठीक करने का सबसे साफ तरीका होगा props.prop का उपयोग state.content के बजाय <A> घटक की render विधि में करें। तो आपकी A कक्षा इस तरह दिखेगी:

class A extends Component {
    render() {
        const { prop } = this.props;
        return <div>{ prop }</div>;
    }
}

यदि आपको prop प्रोप लेना है और <A> घटक की स्थिति में इसका उपयोग करना है, तो आप componentDidUpdate का उपयोग कर सकते हैं। यहाँ एक उदाहरण है:

class A extends Component {
    constructor(props) {
        super(props);
        this.state = {content: props.prop};
    }

    componentDidUpdate(prevProps) {
        if (prevProps.prop !== this.props.prop) {
            this.setState({content: this.props.prop});
        }
    }

    render() {
        const { content } = this.state;
        return <div>{ content }</div>
    }
}
2
Henry Woody 19 सितंबर 2018, 11:25

रिएक्ट कंस्ट्रक्टर को केवल एक बार कॉल करेगा। वह अपेक्षित परिणाम है। ऐसा लगता है कि आप प्रॉपर के आधार पर घटक ए की स्थिति को अपडेट करने की कोशिश कर रहे हैं। आप या तो सीधे प्रोप का उपयोग कर सकते हैं या कंपोनेंटडिडअपडेट जीवनचक्र विधि का उपयोग कर सकते हैं, जैसा कि हेनरी ने सुझाव दिया था। एक और तरीका है स्टेटिक मेथड getDerivedStateFromProps का उपयोग करके पास किए गए प्रोप के आधार पर स्टेट को अपडेट करना।

static getDerivedStateFromProps(props, state) {
    return ({
        content: props.prop
    });
}
1
Filipe Valente 19 सितंबर 2018, 11:29