ReactJS levenscyclusmethode binnen een functiecomponent

In plaats van mijn componenten in een klasse te schrijven, zou ik de functiesyntaxis willen gebruiken.

Hoe overschrijf ik componentDidMount, componentWillMountin functiecomponenten?
Is het zelfs mogelijk?

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>  
    )
}

Antwoord 1, autoriteit 100%

Bewerken:met de introductie van Hookshet is mogelijk om zowel een levenscyclusgedrag als de status in de functionele componenten te implementeren. Momenteel

Hooks zijn een voorstel voor een nieuwe functie waarmee u status en andere kunt gebruiken
Reageer op functies zonder een klasse te schrijven. Ze zijn uitgebracht in React als onderdeel van v16.8.0

useEffecthook kan worden gebruikt om levenscyclusgedrag te repliceren, en useStatekan worden gebruikt om status op te slaan in een functiecomponent.

Basissyntaxis:

useEffect(callbackFunction, [dependentProps]) => cleanupFunction

U kunt uw use-case implementeren in hooks zoals

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>  
    )
}

useEffectkan ook een functie retourneren die wordt uitgevoerd wanneer de component wordt ontkoppeld. Dit kan worden gebruikt om zich af te melden voor luisteraars, waarbij het gedrag van componentWillUnmountwordt nagebootst:

Bijvoorbeeld: componentWillUnmount

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

Om useEffectafhankelijk te maken van specifieke gebeurtenissen, kunt u het een reeks waarden geven om te controleren op wijzigingen:

Bijvoorbeeld: componentDidUpdate

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

Equivalent haken

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

Als u deze array opneemt, zorg er dan voor dat u alle waarden van het componentbereik opneemt die in de loop van de tijd veranderen (rekwisieten, status), anders kunt u uiteindelijk verwijzen naar waarden uit eerdere renders.

Er zijn enkele subtiliteiten bij het gebruik van useEffect; bekijk de API Here.


Vóór v16.7.0

De eigenschap van functiecomponenten is dat ze geen toegang hebben tot de levenscyclusfuncties van Reacts of het sleutelwoord this. U moet de klasse React.Componentuitbreiden als u de levenscyclusfunctie wilt gebruiken.

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>  
    )
  }
}

Functiecomponenten zijn handig wanneer u uw Component alleen wilt weergeven zonder dat er extra logica nodig is.


Antwoord 2, autoriteit 29%

U kunt react-pure-lifecyclegebruiken om levenscyclusfuncties toe te voegen aan functionele componenten.

Voorbeeld:

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);

Antwoord 3, autoriteit 11%

Je kunt je eigen “levenscyclusmethoden” maken met hakenvoor maximale nostalgie.

Hulpfuncties:

import { useEffect, useRef } from "react";
export const useComponentDidMount = handler => {
  return useEffect(() => handler(), []);
};
export const useComponentDidUpdate = (handler, deps) => {
  const isInitialMount = useRef(true);
  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false;
      return;
    }
    return handler();
  }, deps);
};
export const useComponentWillUnmount = handler => {
  return useEffect(() => handler, []);
};

Gebruik:

import {
  useComponentDidMount,
  useComponentDidUpdate,
  useComponentWillUnmount
} from "./utils";
export const MyComponent = ({ myProp }) => {
  useComponentDidMount(() => {
    console.log("Component did mount!");
  });
  useComponentDidUpdate(() => {
    console.log("Component did update!");
  });
  useComponentDidUpdate(() => {
    console.log("myProp did update!");
  }, [myProp]);
  useComponentWillUnmount(() => {
    console.log("Component will unmount!");
  });
  return <div>Hello world</div>;
};  

Antwoord 4, autoriteit 4%

Oplossing één:
Je kunt de nieuwe react HOOKSAPI gebruiken. Momenteel in React v16.8.0

Met haken kun je meer van de functies van React gebruiken zonder klassen.
Hooks bieden een directere API voor de React-concepten die je al kent: rekwisieten, staat, context, refs en levenscyclus.
Hooks lost alle problemen op met Recompose.

Een opmerking van de auteur van recompose(acdlite, 25 oktober 2018):

Hallo! Ik heb Recompose ongeveer drie jaar geleden gemaakt. Ongeveer een jaar later
dat, ik kwam bij het React-team. Vandaag hebben we een voorstel aangekondigd voor:
Haken. Hooks lost alle problemen op waarmee ik probeerde aan te pakken
Drie jaar geleden opnieuw samenstellen, en daarbovenop nog meer. ik zal zijn
het stopzetten van actief onderhoud van dit pakket (exclusief misschien
bugfixes of patches voor compatibiliteit met toekomstige React-releases), en
aanbevelen dat mensen in plaats daarvan Hooks gebruiken. Uw bestaande code met
Recompose werkt nog steeds, verwacht alleen geen nieuwe functies.

Oplossing twee:

Als je een react-versie gebruikt die geen hooks ondersteunt, geen zorgen, gebruik recompose(Een React-hulpriem voor functiecomponenten en componenten van hogere orde.) in plaats daarvan. U kunt recomposegebruiken om lifecycle hooks, state, handlers etcaan een functiecomponent te koppelen.

Hier is een renderloze component die levenscyclusmethodenkoppelt via de levenscyclus-HOC (van opnieuw samenstellen).

// 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);

Antwoord 5

Volgens de documentatie:

import React, { useState, useEffect } from 'react'
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
});

zie React-documentatie


Antwoord 6

componentDidMount

useEffect(()=>{
   // code here
})

componentWillMount

useEffect(()=>{
   return ()=>{ 
                //code here
              }
})

componentDidUpdate

useEffect(()=>{
    //code here
    // when userName state change it will call     
},[userName])

Antwoord 7

Je kunt gebruik maken van de create-react-class module.
Officiële documentatie

Natuurlijk moet je het eerst installeren

npm install create-react-class

Hier is een werkend voorbeeld

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')
)

Antwoord 8

als je react 16.8 gebruikt, kun je react Hooks gebruiken…
React Hooks zijn functies waarmee u kunt “haken” in de React-status en levenscycluskenmerken van functiecomponenten…
docs

Other episodes