componentWillReceiveProps, componentDidUpdate für React Hook
Lesezeit: 7 Minuten
Deng Zhebin
Ich stoße auf zwei Herausforderungen:
Auch wenn, laut React-Richtlinie, abgeleiteter Zustand wird davon abgeraten, aber einige Grenzfälle brauchen es immer noch.
In Bezug auf eine funktionale Komponente mit React Hook, Was ist die äquivalente Implementierung mit React Hook, wenn ich einen abgeleiteten Zustand benötige, der in der Klassenkomponente bei jedem übergeordneten Rendering in componentWillReceiveProps aktualisiert wird
siehe unten Codebeispiel:
class App extends Component {
constructor(props) {
super(props);
this.state = {
count: props.count > 100 ? 100 : props.count,
}
}
/*What is the equivalent implementation when React Hook is used here componentWillReceiveProps*/
componentWillReceiveProps(nextProps) {
if (nextProps.count !== this.props.count) {
this.setState({
count: nextProps.count > 100 ? 100 : nextProps.count
});
}
}
render() {
return ( <
div > {
this.state.count
} <
/div>
);
}
}
export default App;
Wie für componentDidUpdate hat componentDidUpdate sein Gegenstück, wenn React Hook verwendet wird, Sie müssen es wie folgt verwenden:
Der zweite Parameter für useEffect stellt sicher, dass Code nur ausgeführt wird, wenn sich Prop ändert, aber Was ist, wenn ich entsprechende Aufgaben basierend auf mehreren entsprechenden Requisitenänderungen ausführen möchte?? wie man es hinbekommt mit useEffect?
siehe unten Codebeispiel:
class App extends Component {
/*What is the equivalent implementation when functional component with React Hook is used here */
componentDidUpdate(prevProps, prevState) {
if (prevProps.groupName !== this.props.groupName) {
console.log('Let'
's say, I do want to do some task here only when groupName differs');
} else if (prevProps.companyName !== this.props.companyName) {
console.log('Let'
's say, I do want to do some different task here only when companyName differs');
}
}
render() {
/*for simplicity, render code is ignored*/
return null;
}
}
export default App;
fgonzalez
Der Reaktionshaken entspricht dem alten componentWillReceive Requisiten können mit dem gemacht werden useEffect Hook, indem Sie einfach die Prop angeben, die wir auf Änderungen im Abhängigkeitsarray überwachen möchten.
Nachdem ich einige umfangreiche Recherchen zu diesem Thema durchgeführt habe, würde ich argumentieren, dass Ihre Erklärung von componentWillReceiveProps falsch ist. Das Problem ist also, dass das Ersetzen von „componentWillReceiveProps“ schwierig ist, da es sich um eine Pre-Render-Funktion handelt. Dies ist bei Reaktionshaken nicht der Fall. Sie können useRef() verwenden, um die vorherige Stütze zu speichern und sie mit der aktuellen in der useEffect-Funktion zu vergleichen, um zu versuchen, die Funktionalität zu replizieren, aber selbst das ist möglicherweise nicht genau ein 1:1-Ersatz.
– Zach Pedigo
20. Oktober 2020 um 15:09 Uhr
Du kannst den … benutzen useMemo Haken, um eine Berechnung zu speichern und zu setzen props.count in dem als zweites Argument angegebenen Array, um den Wert neu zu berechnen, wenn er sich ändert.
Der einfachste Weg, separate Effekte zu erzielen, wenn sich separate Requisiten ändern, besteht darin, mehrere zu erstellen useEffect Hooks, die nur ausgeführt werden, wenn sich eine der separaten Requisiten ändert.
const { useState, useEffect } = React;
function App() {
const [groupName, setGroupName] = useState('foo');
const [companyName, setCompanyName] = useState('foo');
useEffect(() => {
setTimeout(() => {
setGroupName('bar');
}, 1000);
setTimeout(() => {
setCompanyName('bar');
}, 2000);
}, []);
return <DisplayGroupCompany groupName={groupName} companyName={companyName} />;
}
function DisplayGroupCompany(props) {
useEffect(() => {
console.log("Let's say, I do want to do some task here only when groupName differs");
}, [props.groupName])
useEffect(() => {
console.log("Let's say,I do want to do some different task here only when companyName differs");
}, [props.companyName])
return <div> {props.groupName} - {props.companyName} </div>;
}
ReactDOM.render(<App />, document.getElementById("root"));
Wenn Sie den useMemo-Hook oben auf Ihrer Komponente verwenden und ihn von all Ihren Requisiten abhängig machen, wird er jedes Mal vor allem ausgeführt, wenn sich Requisiten ändern. useEffect wird nach dem aktualisierten Rendern ausgelöst und da es von allen Requisiten abhängig ist, wird es nach einem erneuten Rendern von allen Requisiten ausgelöst.
const Component = (...props) => {
// useState, useReducer if have
useMemo(() => {
// componentWillReceiveProps
},[...props]);
// ...other logic and stuff
useEffect(() => {
// componentDidUpdate
}, [...props]);
};
Ich bin froh, das zu wissen, es ist wirklich hilfreich, den Unterschied zwischen diesen zu erkennen. Vielen Dank ..!
– Sanat Gupta
15. Oktober 2020 um 17:45 Uhr
Thien Ly
setCount löst ein erneutes Rendern aus. Verwenden useEffect mit [count] da das Abhängigkeitsarray sicherstellt, dass der Hook nur Aufrufe durchführt setCount Wenn countDer Wert von ändert sich.
So gehen Sie vor, um alles zu ersetzen componentWillReceiveProps Logik, die Sie sonst vielleicht im alten klassenbasierten React-Stil geschrieben hätten. Ich finde das “Jeder Renderer hat seine eigenen Requisiten und seinen eigenen Status“Prinzip nützlich: Wenn Sie nur dann ein erneutes Rendern auslösen möchten, wenn sich bestimmte Requisiten ändern, können Sie mehrere haben useEffect Haken.
useEffect(() => {
count > 100 ? setCount(100) : setCount(count)
}, [count])
useEffect(() => {
console.log('groupName has changed');
// do something with groupName
}, [groupName])
useEffect(() => {
console.log('companyName has changed');
// do something with companyName
}, [companyName])
Kevin F.
In Ihrem Szenario müssen Sie nicht verwenden oder neu implementieren getDerivedStateFromProps überhaupt. Sie müssen nur eine neue Variable erstellen, um die neue Form von Daten zu erhalten. Die Verwendung von state in diesem Szenario führt nur zu einem erneuten Rendern, was in Bezug auf die Leistung nicht gut ist.
Wenn Sie wirklich einen separaten Status verwenden müssen, können Sie so etwas verwenden
import React, { useState } from 'react';
const App = ({ count }) => {
const [derivedCounter, setDerivedCounter] = useState(
count > 100 ? 100 : count
);
useEffect(() => {
setDerivedCounter(count > 100 ? 100 : count);
}, [count]); // this line will tell react only trigger if count was changed
return <div>Counter: {derivedCounter}</div>;
};
ist es nicht wahr, dass prop schreibgeschützt ist? und das Wechseln der Stütze bricht auch die reine Funktion. Rechts?
– MPV
4. August 2019 um 7:06 Uhr
kwoxer
einfach durch Verwendung von useEffect wie folgt.
useEffect( () => {
props.actions.fetchSinglePost(props.match.params.id); //> I'm dispatching an action here.
}, [props.comments]) //> and here to watch comments and call the action in case there is any change.
ist es nicht wahr, dass prop schreibgeschützt ist? und das Wechseln der Stütze bricht auch die reine Funktion. Rechts?
– MPV
4. August 2019 um 7:06 Uhr
In einem Fall möchten Sie ein Protokollsystem wie z warum hast du gerendertund Sie brauchen die nextProps Hier hilft Haken.
An der alten Lebenszyklusfunktion ausgerichtet, um Sachen in Props und nextProps umzubenennen