एक फंक्शन कंपोनेंट के अंदर रिएक्टजेएस जीवन चक्र विधि


135

एक कक्षा के अंदर अपने घटकों को लिखने के बजाय, मैं इसके बजाय फ़ंक्शन सिंटैक्स का उपयोग करना चाहूंगा।

मैं कैसे ओवरराइड करते componentDidMount, componentWillMountसमारोह घटकों के अंदर?
क्या यह भी संभव है?

const grid = (props) => {
    console.log(props);
    let {skuRules} = props;

    const componentDidMount = () => {
        if(!props.fetched) {
            props.fetchRules();
        }
        console.log('mount it!');
    };
    return(
        <Content title="Promotions" breadcrumbs={breadcrumbs} fetched={skuRules.fetched}>
            <Box title="Sku Promotion">
                <ActionButtons buttons={actionButtons} />
                <SkuRuleGrid 
                    data={skuRules.payload}
                    fetch={props.fetchSkuRules}
                />
            </Box>      
        </Content>  
    )
}

1
कार्यात्मक घटकों में जीवनचक्र के तरीके नहीं हैं। क्योंकि वे सिर्फ कार्य हैं। और कार्यों के तरीके नहीं हैं। इसके लिए कक्षाएं हैं
हिमस्खलन 1

जवाबों:


149

संपादित करें: इसकी शुरूआत के साथ Hooksकार्यात्मक घटकों में एक जीवनचक्र तरह के व्यवहार के साथ-साथ राज्य को लागू करना संभव है। वर्तमान में

हुक एक नई सुविधा का प्रस्ताव है जो आपको कक्षा लिखे बिना राज्य और अन्य प्रतिक्रिया सुविधाओं का उपयोग करने देता है। वे प्रतिक्रिया में v16.8.0 के एक भाग के रूप में जारी किए जाते हैं

useEffectहुक का उपयोग जीवनचक्र व्यवहार को दोहराने के लिए किया जा सकता है, और useStateइसका उपयोग फ़ंक्शन घटक में स्थिति को संग्रहीत करने के लिए किया जा सकता है।

मूल सिंटैक्स:

useEffect(callbackFunction, [dependentProps]) => cleanupFunction

आप अपने उपयोग के मामले को हुक की तरह लागू कर सकते हैं

const grid = (props) => {
    console.log(props);
    let {skuRules} = props;

    useEffect(() => {
        if(!props.fetched) {
            props.fetchRules();
        }
        console.log('mount it!');
    }, []); // passing an empty array as second argument triggers the callback in useEffect only after the initial render thus replicating `componentDidMount` lifecycle behaviour

    return(
        <Content title="Promotions" breadcrumbs={breadcrumbs} fetched={skuRules.fetched}>
            <Box title="Sku Promotion">
                <ActionButtons buttons={actionButtons} />
                <SkuRuleGrid 
                    data={skuRules.payload}
                    fetch={props.fetchSkuRules}
                />
            </Box>      
        </Content>  
    )
}

useEffectएक फ़ंक्शन को भी लौटा सकता है जो घटक के अनमाउंट होने पर चलाया जाएगा। इसका उपयोग श्रोताओं को अनसब्सक्राइब करने के लिए किया जा सकता है componentWillUnmount:

जैसे: कंपोनेंटविल यूमाउंट

useEffect(() => {
    window.addEventListener('unhandledRejection', handler);
    return () => {
       window.removeEventListener('unhandledRejection', handler);
    }
}, [])

useEffectविशिष्ट घटनाओं पर सशर्त बनाने के लिए , आप इसे परिवर्तनों की जांच करने के लिए मूल्यों की एक सरणी प्रदान कर सकते हैं:

जैसे: कंपोनेंटड्यूपडेट

componentDidUpdate(prevProps, prevState) {
     const { counter } = this.props;
     if (this.props.counter !== prevState.counter) {
      // some action here
     }
}

हुक बराबर

useEffect(() => {
     // action here
}, [props.counter]); // checks for changes in the values in this array

यदि आप इस सरणी को शामिल करते हैं, तो समय के साथ बदलने वाले घटक स्कोप से सभी मानों को शामिल करना सुनिश्चित करें (प्रॉप्स, स्टेट), या आप पिछले रेंडरर्स से संदर्भित मानों को समाप्त कर सकते हैं।

उपयोग करने के लिए कुछ सूक्ष्मताएं हैं useEffect; एपीआई की जाँच करें Here


V16.7.0 से पहले

फ़ंक्शन घटकों की संपत्ति यह है कि उनके पास रीसायकल जीवन चक्र फ़ंक्शन या thisकीवर्ड तक पहुंच नहीं है । React.Componentयदि आप जीवनचक्र फ़ंक्शन का उपयोग करना चाहते हैं तो आपको कक्षा का विस्तार करने की आवश्यकता है ।

class Grid extends React.Component  {
    constructor(props) {
       super(props)
    }

    componentDidMount () {
        if(!this.props.fetched) {
            this.props.fetchRules();
        }
        console.log('mount it!');
    }
    render() {
    return(
        <Content title="Promotions" breadcrumbs={breadcrumbs} fetched={skuRules.fetched}>
            <Box title="Sku Promotion">
                <ActionButtons buttons={actionButtons} />
                <SkuRuleGrid 
                    data={skuRules.payload}
                    fetch={props.fetchSkuRules}
                />
            </Box>      
        </Content>  
    )
  }
}

जब आप केवल अतिरिक्त तर्क की आवश्यकता के बिना अपने घटक को प्रस्तुत करना चाहते हैं तो फ़ंक्शन घटक उपयोगी होते हैं।


1
जैसा कि मैंने कहा, आपके घटक में एक तर्क है और आप आवश्यकता चाहते हैं कि आप एक जीवनचक्र फ़ंक्शन का उपयोग करें और आप यह कर सकते हैं कि फंक्शनलियोएनल घटकों के साथ। इसलिए कक्षा का बेहतर उपयोग करें। कार्यात्मक घटक का उपयोग करें जब आपके घटक में कोई अतिरिक्त तर्क न हो
शुभ खत्री

1
यह ध्यान दिया जाना चाहिए कि यह सटीक कंपोनेंटड्यूपडेट समतुल्य नहीं है। useEffect(() => { // action here }, [props.counter])आरंभिक रेंडर पर ट्रिगर किया जाता है जबकि कंपोनेंटड्यूपडेट नहीं करता है।
एस्टुस फ्लास्क

1
passing an empty array as second argument triggers the callback in useEffect only after the initial renderयह सामान बनाने के लिए एक गंदे हैकरी तरीके की तरह लगता है: / उम्मीद है कि प्रतिक्रिया टीम भविष्य के रिलीज में कुछ बेहतर करेगी।
लुकास लेइसिस

3
इसलिए? वह हिस्सा कहां है जहां आप जवाब देते हैं कि कैसे कंपोनविलमाउंट पर कोड चलाना है?
टॉस्कन

59

कार्यात्मक घटकों में जीवनचक्र कार्यों को जोड़ने के लिए आप प्रतिक्रिया-शुद्ध-जीवनचक्र का उपयोग कर सकते हैं ।

उदाहरण:

import React, { Component } from 'react';
import lifecycle from 'react-pure-lifecycle';

const methods = {
  componentDidMount(props) {
    console.log('I mounted! Here are my props: ', props);
  }
};

const Channels = props => (
<h1>Hello</h1>
)

export default lifecycle(methods)(Channels);

3
क्या है Grid? मुझे नहीं लगता कि इसे आपके कोड स्निपेट में कहीं भी परिभाषित किया गया है? यदि आप इसके साथ redux का उपयोग करना चाहते हैं, तो क्या आप ऐसा कुछ प्राप्त कर सकते हैं export default lifecycle(methods)(connect({},{})(ComponentName))?
शॉन क्लेंसी

@SeanClancy देर से प्रतिक्रिया के लिए क्षमा करें। कोड स्निपेट अपडेट किया गया था।
योहन

1
क्या यह एक अच्छा अभ्यास है? क्या मुझे इस एक के लिए पहुंचने से पहले अलग-अलग समाधानों की कोशिश करनी चाहिए या अगर मुझे यह आसान लगता है तो क्या इसका उपयोग करना ठीक है?
SuperSimplePimpleDimple

9

समाधान एक: आप नई प्रतिक्रिया HOOKS API का उपयोग कर सकते हैं । वर्तमान में रिएक्ट v16.8.0 में

हुक आपको कक्षाओं के बिना रिएक्ट की सुविधाओं का अधिक उपयोग करने देते हैं। हुक आपको पहले से ज्ञात प्रतिक्रिया अवधारणाओं के लिए एक अधिक प्रत्यक्ष एपीआई प्रदान करते हैं: सहारा, राज्य, संदर्भ, रेफरी और जीवनचक्र । हुक सभी समस्याओं को सुलझाता है।

लेखक के एक नोट recompose(acdlite, 25 अक्टूबर 2018):

नमस्ते! मैंने लगभग तीन साल पहले Recompose बनाया था। उसके लगभग एक साल बाद, मैं रिएक्ट टीम में शामिल हो गया। आज, हमने हुक के लिए एक प्रस्ताव की घोषणा की। हुक ने उन सभी समस्याओं को हल किया, जिन्हें मैंने तीन साल पहले रेपोम्पोज के साथ संबोधित करने का प्रयास किया था, और उसके ऊपर। मैं इस पैकेज के सक्रिय रखरखाव को बंद कर दूंगा (भविष्य के रिएक्ट रिलीज के साथ संगतता के लिए शायद बगफिक्स या पैच को छोड़कर), और यह अनुशंसा करता हूं कि लोग इसके बजाय हुक का उपयोग करें। आपका मौजूदा कोड अभी भी काम करेगा, बस किसी नई सुविधा की उम्मीद न करें।

समाधान दो:

यदि आप प्रतिक्रिया संस्करण का उपयोग कर रहे हैं जो हुक का समर्थन नहीं करता है, तो कोई चिंता नहीं, इसके बजाय recompose(फ़ंक्शन घटकों और उच्च-क्रम घटकों के लिए एक प्रतिक्रिया उपयोगिता बेल्ट) का उपयोग करें। आप एक फ़ंक्शन घटक से recomposeसंलग्न lifecycle hooks, state, handlers etcकरने के लिए उपयोग कर सकते हैं ।

यहां एक रेंडर-कम घटक है जो जीवनचक्र एचओसी (पुन: प्रस्ताव से) के माध्यम से जीवनचक्र विधियों को संलग्न करता है।

// taken from https://gist.github.com/tsnieman/056af4bb9e87748c514d#file-auth-js-L33

function RenderlessComponent() {
  return null; 
}

export default lifecycle({

  componentDidMount() {
    const { checkIfAuthed } = this.props;
    // Do they have an active session? ("Remember me")
    checkIfAuthed();
  },

  componentWillReceiveProps(nextProps) {
    const {
      loadUser,
    } = this.props;

    // Various 'indicators'..
    const becameAuthed = (!(this.props.auth) && nextProps.auth);
    const isCurrentUser = (this.props.currentUser !== null);

    if (becameAuthed) {
      loadUser(nextProps.auth.uid);
    }

    const shouldSetCurrentUser = (!isCurrentUser && nextProps.auth);
    if (shouldSetCurrentUser) {
      const currentUser = nextProps.users[nextProps.auth.uid];
      if (currentUser) {
        this.props.setCurrentUser({
          'id': nextProps.auth.uid,
          ...currentUser,
        });
      }
    }
  }
})(RenderlessComponent);

4

आप अपने स्वयं के जीवन चक्र के तरीके बना सकते हैं।

उपयोगिता कार्य

import { useEffect, useRef } from "react";

export const componentDidMount = handler => {
  return useEffect(() => {
    return handler();
  }, []);
};

export const componentDidUpdate = (handler, deps) => {
  const isInitialMount = useRef(true);

  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false;

      return;
    }

    return handler();
  }, deps);
};

प्रयोग

import { componentDidMount, componentDidUpdate } from "./utils";

export const MyComponent = ({ myProp }) => {
  componentDidMount(() => {
    console.log("Component did mount!");
  });

  componentDidUpdate(() => {
    console.log("Component did update!");
  });

  componentDidUpdate(() => {
    console.log("myProp did update!");
  }, [myProp]);
};  


0

यदि आपको React LifeCycle का उपयोग करने की आवश्यकता है, तो आपको कक्षा का उपयोग करने की आवश्यकता है।

नमूना:

import React, { Component } from 'react';

class Grid extends Component {

 constructor(props){
  super(props)
 }

 componentDidMount () { /* do something */ }

 render () { 
   return <h1>Hello</h1>
 }

}

2
मैं कक्षा का उपयोग नहीं करना चाहता।
आफताब नवीद

3
सवाल यह था कि जीवनशैली के तरीकों को एक कार्यात्मक घटक के साथ कैसे उपयोग किया जाए, एक वर्ग नहीं।
माइक

अब, रिएक्ट हुक के साथ
गेब्रियल फरेरा

0

आप क्रिएट-रिएक्शन-क्लास मॉड्यूल का उपयोग कर सकते हैं। आधिकारिक दस्तावेज

बेशक आपको पहले इसे स्थापित करना होगा

npm install create-react-class

यहाँ एक कार्य उदाहरण है

import React from "react";
import ReactDOM from "react-dom"
let createReactClass = require('create-react-class')


let Clock = createReactClass({
    getInitialState:function(){
        return {date:new Date()}
    },

    render:function(){
        return (
            <h1>{this.state.date.toLocaleTimeString()}</h1>
        )
    },

    componentDidMount:function(){
        this.timerId = setInterval(()=>this.setState({date:new Date()}),1000)
    },

    componentWillUnmount:function(){
        clearInterval(this.timerId)
    }

})

ReactDOM.render(
    <Clock/>,
    document.getElementById('root')
)

0

यदि आप 16.8 प्रतिक्रिया का उपयोग कर रहे हैं, तो आप प्रतिक्रिया हुक का उपयोग कर सकते हैं ... प्रतिक्रिया हुक ऐसे कार्य हैं जो आपको "हुक इन" प्रतिक्रिया घटकों और फ़ंक्शन घटकों से जीवनचक्र सुविधाओं ... डॉक्स

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.