मेरे पास एक निचला स्तर घटक है जिसका उपयोग मेरे आवेदन में सफलता/त्रुटि संदेश प्रदर्शित करने के लिए किया जाता है। वर्तमान में यह अपने राज्य के लिए सहारा का उपयोग कर रहा है, जिसने इस बिंदु तक काम किया है। मुझे जिस समस्या का सामना करना पड़ रहा है वह यह है कि जब एक निश्चित घटक में लौटाया जाता है तो घटक एक बार प्रस्तुत होने के बाद राज्य नहीं बदल रहा है। अर्थात। संदेश एक बार सही ढंग से दिखाई देगा और फिर यह फिर से दिखाई नहीं देगा क्योंकि स्थिति झूठी पर सेट रहती है।

यहां वह फ़ंक्शन है जो घटक को प्रस्तुत करता है। यह फ़ंक्शन मूल घटक में बैठता है।

renderSnackBar(type, message) {

    console.log('snackbar function invoked');

    return <Snackbar open={true} type={type} message={message} />
  }

यहाँ बाल घटक है

class MySnackbar extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
    open: this.props.open,
  };
}

  handleClose = (event, reason) => {
    if (reason === 'clickaway') {
      return;
    }

    this.setState({ open: false });
  };

  render() {

    const { type, message } = this.props

    let icon = <SuccessIcon color={colors.lightBlue} />
    let color = colors.lightBlue
    console.log('state', this.state, 'props', this.props);

    switch (type) {
      case 'Error':
        icon = <ErrorIcon color={colors.red} />
        color = colors.red
        break;
      case 'Success':
        icon = <SuccessIcon color={colors.lightBlue} />
        color = colors.lightBlue
        break;
      case 'Warning':
        icon = <WarningIcon color={colors.orange} />
        color = colors.orange
        break;
      case 'Info':
        icon = <InfoIcon color={colors.lightBlue} />
        color = colors.lightBlue
        break;
      default:
        icon = <SuccessIcon color={colors.lightBlue} />
        color = colors.lightBlue
        break;
    }

    return (
      <Snackbar
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'left',
        }}
        open={this.state.open}
        autoHideDuration={6000}
        onClose={this.handleClose}
        message={
          <div style={{ padding: '12px 24px', borderLeft: '5px solid '+color, borderRadius: '4px'}}>
            {icon}
            <div style={{ display: 'inline-block', verticalAlign: 'middle', maxWidth: '400px' }}>
              <Typography variant='body1' style={{ fontFamily: 'Montserrat-SemiBold', fontSize: '12px' }}>{type}</Typography>
              <Typography variant='body1' style={{ fontFamily: 'Montserrat-Medium', fontSize: '10px', color: colors.darkGray }} noWrap>{message}</Typography>
            </div>
          </div>
        }
        action={[
          <IconButton
            key="close"
            aria-label="Close"
            color={colors.darkGray}
            onClick={this.handleClose}
          >
            <CloseIcon />
          </IconButton>,
        ]}
      />
    );
  }
}

export default MySnackbar;

राज्य को इनिशियलाइज़ करने के लिए प्रॉप्स का उपयोग करके मैं जो इकट्ठा करता हूं, वह एक एंटीपैटर्न है। मैं राज्य के रूप में प्रॉप्स का उपयोग किए बिना इस घटक का उपयोग कैसे कर सकता हूं?

0
larry burns 26 सितंबर 2019, 05:09
स्नैकबार खोलने का कार्यक्रम क्या है?
 – 
Joseph D.
26 सितंबर 2019, 05:22
@ जोसेफ डी। मैं मूल घटकों में अभिव्यक्ति का उपयोग कर रहा हूँ विधि प्रस्तुत करना। विशेष रूप से मेरे ग्रिड के नीचे वापसी में। { error && this.renderSnackBar('Error', error) } { success && this.renderSnackBar('Success', success ) } </Grid>
 – 
larry burns
26 सितंबर 2019, 05:28

2 जवाब

मूल रूप से, आपके पास अभी जो समस्या है, वह इस तथ्य के कारण है कि आपके स्नैकबार को open होना चाहिए या नहीं, यह निर्धारित करने के लिए आपके पास सत्य के 2 स्रोत हैं (प्रॉप्स से 1 और राज्य से 1)।

तो, हम जो करना चाहते हैं वह यह है कि आपके घटक के लिए सत्य का केवल 1 स्रोत है। आमतौर पर, हम props को सत्य के स्रोत के रूप में रखना चाहते हैं, न कि state को।

हम आपके स्नैकबार में onClose नाम का एक प्रॉप जोड़ सकते हैं, और स्नैकबार को handleClose के अंदर फंक्शन को इनवाइट करने के लिए कह सकते हैं। onClose को मूल घटक से open मान बदलना चाहिए, इसलिए स्नैकबार को दिया गया मान तदनुसार अपडेट किया जाता है। अब, स्नैकबार के पास अब अपना राज्य नहीं होना चाहिए, यह केवल इसके पास दिए गए प्रॉप्स पर भरोसा कर सकता है। यहां कोडसैंडबॉक्स पर कार्यान्वयन का एक उदाहरण दिया गया है

1
Jackyef 26 सितंबर 2019, 05:25
दुर्भाग्य से इस फिक्स को करने के लिए एप्लिकेशन को एक टन रिफॉर्मेटिंग की आवश्यकता होगी क्योंकि मुझे इस राज्य को अपने सभी शीर्ष स्तर के कंटेनरों में जोड़ना होगा और इसे प्रॉप्स के रूप में ड्रिल करना होगा। मैं एक फिक्स की तलाश में हूं जिसे मैं अपने वर्तमान आर्किटेक्चर के साथ कार्यान्वित कर सकता हूं।
 – 
larry burns
26 सितंबर 2019, 05:37
अगर ऐसा है, तो मैं open मान को Context. फिर, स्नैकबार को केवल संदर्भ से open मान पढ़ने की आवश्यकता होगी, और handleClose (स्नैकबार में ही) केवल open मान को संदर्भ में false पर सेट करेगा। तो अब आप या तो state या props पर निर्भर नहीं हैं, बल्कि केवल Context पर निर्भर हैं। विचार वही है, इसे बनाओ ताकि आपके पास सत्य का केवल 1 स्रोत हो। लेकिन प्रसंग के साथ, आपको इतने सारे स्तरों को सहारा देने के लिए मूल्य को पारित करने की आवश्यकता नहीं है।
 – 
Jackyef
26 सितंबर 2019, 05:41
क्या आप विस्तार से बता सकते हैं कि संदर्भ से आपका क्या मतलब है? क्या आपका मतलब संदर्भ एपीआई का उपयोग करना है?
 – 
larry burns
26 सितंबर 2019, 05:43
हां, मैं संदर्भ एपीआई की बात कर रहा हूं।
 – 
Jackyef
26 सितंबर 2019, 05:51
यह रिफैक्टरिंग बहुत जरूरी है, अन्यथा यदि आप इस मौजूदा समस्या को ठीक करने में सक्षम हैं, तो भी आप इस परियोजना के लिए और अधिक तकनीकी ऋण बना रहे हैं। कॉन्टेक्स्ट एपीआई (जो इस मामले में लागू करना आसान है) का उपयोग करने के अलावा, दूसरा विकल्प मोबएक्स या रेडक्स होगा, या केवल प्रोप को मैन्युअल रूप से नीचे से पास करें।
 – 
Liren Yeo
26 सितंबर 2019, 05:55

जब भी आपको ओपन प्रोप प्राप्त होता है जो कि राज्य के समान नहीं होता है तो आप के साथ राज्य बदल सकते हैं getDerivedStateFromProps

static getDerivedStateFromProps({open}, state) {
  if (open !==state.open) {
    //use open from props
    return {
      ...state,
      open
    };
  }  
  // Return null to indicate no change to state.
  return null;
}

अब आपके पास एक ऐसा घटक हो सकता है जो रेंडरस्नैकबार को कॉल करने के तरीके के आधार पर अब बंद नहीं होता है, यदि ऐसा है तो मुझे इस बारे में और जानने की आवश्यकता है कि आप रेंडरस्नैकबार फ़ंक्शन को कैसे कॉल करते हैं।

0
HMR 26 सितंबर 2019, 11:39