reactjs - क्या आप सेटस्टैट पर कॉल किए बिना रेंडर करने के लिए एक रिएक्ट घटक को बाध्य कर सकते हैं?




react-jsx (12)

मेरे पास एक बाहरी (घटक के लिए), अवलोकन योग्य वस्तु है जिसे मैं बदलावों के लिए सुनना चाहता हूं। जब ऑब्जेक्ट को अपडेट किया जाता है तो यह परिवर्तन की घटनाओं का उत्सर्जन करता है, और फिर मैं किसी परिवर्तन का पता लगाने पर घटक को फिर से प्रस्तुत करना चाहता हूं।

शीर्ष-स्तर React.render यह संभव हो गया है, लेकिन एक घटक के भीतर यह काम नहीं करता है (जो render विधि के बाद से कुछ समझ में आता है) बस एक वस्तु लौटाता है।

यहाँ एक कोड उदाहरण है:

export default class MyComponent extends React.Component {

  handleButtonClick() {
    this.render();
  }

  render() {
    return (
      <div>
        {Math.random()}
        <button onClick={this.handleButtonClick.bind(this)}>
          Click me
        </button>
      </div>
    )
  }
}

आंतरिक रूप से बटन पर क्लिक करने से यह this.render() कॉल this.render() , लेकिन वास्तव में इसका प्रतिपादन होने का कारण नहीं है (आप इसे कार्रवाई में देख सकते हैं क्योंकि {Math.random()} द्वारा बनाया गया पाठ परिवर्तित नहीं होता है)। हालाँकि, अगर मैं इसके बजाय। this.render() this.setState() कॉल करता हूँ। this.render() , यह ठीक काम करता है।

इसलिए मुझे लगता है कि मेरा सवाल यह है: क्या रिएक्टर के घटकों को रेंडर करने के लिए राज्य की आवश्यकता है? क्या राज्य को बदलने के बिना घटक को मांग पर अद्यतन करने के लिए मजबूर करने का एक तरीका है?


इसलिए मुझे लगता है कि मेरा सवाल यह है: क्या रिएक्टर के घटकों को रेंडर करने के लिए राज्य की आवश्यकता है? क्या राज्य को बदलने के बिना घटक को मांग पर अद्यतन करने के लिए मजबूर करने का एक तरीका है?

अन्य उत्तरों ने यह बताने की कोशिश की है कि आप कैसे हो सकते हैं, लेकिन मुद्दा यह है कि आपको ऐसा नहीं करना चाहिए । यहां तक ​​कि कुंजी को बदलने का हैकी समाधान बिंदु को याद करता है। रिएक्ट की शक्ति मैन्युअल रूप से प्रबंधित करने का नियंत्रण दे रही है जब कुछ को प्रस्तुत करना चाहिए, और इसके बजाय बस अपने आप को इनपुट पर कुछ मैप करना चाहिए। फिर इनपुट्स की सप्लाई स्ट्रीम।

यदि आपको मैन्युअल रूप से फिर से प्रस्तुत करने की आवश्यकता है, तो आप निश्चित रूप से कुछ सही नहीं कर रहे हैं।


HOC का उपयोग करके बाइंड स्टोर में परिवर्तन

HOC (उच्च क्रम घटक) पैटर्न का उपयोग करके, आप अपने रिएक्ट घटकों को लपेट सकते हैं और जब आपके स्टोर बदलते हैं तो स्वत: अपडेट होते हैं। यह एक फ्रेमवर्क के बिना बहुत हल्का वजन दृष्टिकोण है।

withStores HOC स्टोर अपडेट को संभालता है

import React, { Component } from 'react'

export default function(/* store1, store2, store3... */) {
  const storeArgs = Array.prototype.slice.call(arguments)
  return function(WrappedComponent) {
    return class WithStore extends Component {
      constructor(props) {
        super(props)
        this.state = {
          lastUpdated: Date.now()
        }
        this.stores = storeArgs
      }

      _onChange = () => {
        this.setState({ lastUpdated: Date.now() })
      }

      componentWillMount = () => {
        this.stores && this.stores.forEach(store => {
          // each store has a common change event to subscribe to
          store.on('change', this._onChange)
        })
      }

      componentWillUnmount = () => {
        this.stores && this.stores.forEach(store => {
          store.off('change', this._onChange)
        })
      }

      render() {
        return <WrappedComponent 
                 lastUpdated={this.state.lastUpdated}
                 {...this.props}  />
      }
    }
  }
}

कैसे इस्तेमाल करे

import React, { Component } from 'react'
import { View, Text, Button } from 'react-native'
import withStores from './withStores'
import userStore from './stores/users'

class MyView {
  _increaseUserCount = () => {
    userStore.setState({ userCount: userStore.state.count + 1 })
  }

  render() {
    return (
      <View>
        <Text>User count: {userStore.state.count}</Text>
        <Button
          title="Increase User Count"
          onPress={this._increaseUserCount}
        />
      </View>
    )
  }
}

return withStores(userStore)(MyView)

सरल स्टोर वर्ग उदाहरण

var ee = require('event-emitter')
export default class Store {
  constructor() {
    this._state = {}
    this._eventEmitter = ee({})
  }
  get state() {
    return this._state
  }
  setState(newState) {
    this._state = {...this._state, ...newState}
    this._eventEmitter.emit('change')
  }
  on(ev, fn) {
    this._eventEmitter.on(ev, fn)
  }
  off(ev, fn) {
    this._eventEmitter.off(ev, fn)
  }
}

एकल के रूप में स्टोर उदाहरण

import Store from './Store'

const myStore = new Store()
export default myStore

यह वास्तव में घटक पेड़ों की कम गहराई वाली छोटी परियोजनाओं के लिए है । इसका कारण यह है कि यदि आप घटकों के एक बड़े पेड़ के लिए इसका उपयोग करते हैं, तो यह स्टोर के लिए अपडेट करने के लिए क्या भागों पर बहुत चयनात्मक नहीं है, बस स्टोर ही अपडेट को ट्रिगर करता है।

आप ठीक होंगे यदि आप अपने स्टोर को अधिक ग्रेन्युलर अंदाज में विभाजित करते हैं लेकिन फिर से, यही कारण है कि रिडक्स अच्छा है क्योंकि यह दोनों दानेदार के रूप में आवश्यक हो सकता है और केवल एक ही स्टोर की आवश्यकता होती है, लेकिन एक छोटी परियोजना पर भी विषम बायलरप्लेट है।


forceUpdate (), लेकिन हर बार जब भी मैंने कभी किसी को इसके बारे में बात करते सुना है, तो इसका अनुसरण किया गया है, आपको कभी भी इसका उपयोग नहीं करना चाहिए।



आप इसे कुछ तरीके से कर सकते हैं:

1. forceUpdate() प्रयोग करें forceUpdate() विधि:

कुछ ग्लिच हैं जो forceUpdate() विधि का उपयोग करते समय हो सकते हैं। एक उदाहरण यह है कि यह shouldComponentUpdate() विधि को अनदेखा करता है और इस बात की परवाह किए बिना कि shouldComponentUpdate() गलत रिटर्न देता है या फिर से रेंडर करेगा। इसके कारण जब संभव हो तो बलप्रयोग () का उपयोग करने से बचना चाहिए।

2. इस पास करना। setState() विधि से करें

कोड की निम्न पंक्ति पिछले उदाहरण के साथ समस्या पर काबू पाती है:

this.setState(this.state);

वास्तव में यह सब वर्तमान स्थिति के साथ वर्तमान स्थिति को अधिलेखित कर रहा है जो पुन: प्रतिपादन को ट्रिगर करता है। यह आवश्यक रूप से चीजों को करने का सबसे अच्छा तरीका नहीं है, लेकिन यह कुछ glitches को पार कर सकता है जो आपको forceUpdate () विधि का उपयोग करके सामना कर सकते हैं।


आपके घटक को पुन: प्रस्तुत करने के कुछ तरीके हैं:

सबसे सरल उपाय बलप्रयोग () विधि का उपयोग करना है:

this.forceUpdate()

एक और उपाय यह है कि राज्य में उपयोग की जाने वाली कुंजी (nonUsedKey) न बनाएं और इस nonUsedKey के अपडेट के साथ setState फ़ंक्शन को कॉल करें:

this.setState({ nonUsedKey: Date.now() } );

या सभी वर्तमान स्थिति को फिर से लिखना:

this.setState(this.state);

प्रॉप्स बदलने से कंपोनेंट रेंडरर भी मिलता है।


एक और तरीका है setState , और संरक्षित अवस्था:

this.setState(prevState=>({...prevState}));


जब आप संवाद करने के लिए दो रिएक्ट घटक चाहते हैं, जो एक संबंध (माता-पिता-बच्चे) से बाध्य नहीं हैं, तो Flux या इसी तरह के आर्किटेक्चर का उपयोग करना उचित है।

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

आम तौर पर आपको forceUpdate() का उपयोग करने से बचने की कोशिश करनी चाहिए। प्रलेखन से:

आम तौर पर आपको बलप्रयोग () के सभी उपयोगों से बचने का प्रयास करना चाहिए और केवल इस से पढ़ा जाना चाहिए। क्रॉप्स और रेंडर में यह। ()। यह आपके एप्लिकेशन को बहुत सरल और अधिक कुशल बनाता है


यह वर्णन करने के लिए कि आप क्या वर्णन कर रहे हैं, कृपया इसे आज़माएँ ।forceUpdate ()।


वास्तव में, forceUpdate() setState() रूप में एकमात्र सही समाधान है setState() यदि shouldComponentUpdate() में अतिरिक्त तर्क लागू किया गया है या जब यह केवल false रिटर्न देता है तो पुन: रेंडर को ट्रिगर नहीं किया जा सकता है।

बलपूर्वक जानकारी()

forceUpdate() को कॉल करने से forceUpdate() कॉल करने के लिए forceUpdate() का कारण बन जाएगा, स्किपिंग shouldComponentUpdate() forceUpdate()

setState ()

setState() हमेशा एक पुनः-ट्रिगर प्रदान करेगा जब तक कि सशर्त प्रतिपादन तर्क shouldComponentUpdate() में लागू न हो shouldComponentUpdate() more...

forceUpdate() को आपके कंपोनेंट के भीतर से इसे कहा जा सकता है forceUpdate() this.forceUpdate()


हम नीचे के रूप में इसका उपयोग कर सकते हैं।

       class MyComponent extends React.Component {



      handleButtonClick = ()=>{
          this.forceUpdate();
     }


 render() {

   return (
     <div>
      {Math.random()}
        <button  onClick={this.handleButtonClick}>
        Click me
        </button>
     </div>
    )
  }
}

 ReactDOM.render(<MyComponent /> , mountNode);

DOM में तत्व 'Math.random' केवल तब भी अपडेट होता है, जब आप घटक को फिर से प्रस्तुत करने के लिए setState का उपयोग करते हैं।

यहाँ सभी उत्तर समझ के लिए प्रश्न को पूरक करने के लिए सही हैं..जैसे हम जानते हैं कि एक घटक को फिर से प्रस्तुत करना है जिसमें से सेटस्टेट ({}) का उपयोग करके किया जाता है बलप्रयोग () का उपयोग करके।

उपरोक्त कोड नीचे के रूप में सेटस्टेट के साथ चलता है।

 class MyComponent extends React.Component {



             handleButtonClick = ()=>{
                this.setState({ });
              }


        render() {
         return (
  <div>
    {Math.random()}
    <button  onClick={this.handleButtonClick}>
      Click me
    </button>
  </div>
)
  }
 }

ReactDOM.render(<MyComponent /> , mountNode);

forceUpdate(); विधि काम करेगी लेकिन setState(); का उपयोग करना उचित है setState();





react-jsx