In plaats van mijn componenten in een klasse te schrijven, zou ik de functiesyntaxis willen gebruiken.
Hoe overschrijf ik componentDidMount
, componentWillMount
in 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 Hooks
het 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
useEffect
hook kan worden gebruikt om levenscyclusgedrag te repliceren, en useState
kan 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>
)
}
useEffect
kan 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 componentWillUnmount
wordt nagebootst:
Bijvoorbeeld: componentWillUnmount
useEffect(() => {
window.addEventListener('unhandledRejection', handler);
return () => {
window.removeEventListener('unhandledRejection', handler);
}
}, [])
Om useEffect
afhankelijk 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.Component
uitbreiden 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 recompose
gebruiken om lifecycle hooks, state, handlers etc
aan 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(() => {
});
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