Gibt es Möglichkeiten, componentDidMount
in React Funktionskomponenten über Hooks zu simulieren ?
Antworten:
Für die stabile Version von Hooks (React Version 16.8.0+)
Zum componentDidMount
useEffect(() => {
// Your code here
}, []);
Zum componentDidUpdate
useEffect(() => {
// Your code here
}, [yourDependency]);
Zum componentWillUnmount
useEffect(() => {
// componentWillUnmount
return () => {
// Your code here
}
}, [yourDependency]);
In dieser Situation müssen Sie Ihre Abhängigkeit an dieses Array übergeben. Nehmen wir an, Sie haben einen solchen Zustand
const [count, setCount] = useState(0);
Und wenn die Anzahl steigt, möchten Sie Ihre Funktionskomponente neu rendern. Dann useEffect
solltest du so aussehen
useEffect(() => {
// <div>{count}</div>
}, [count]);
Auf diese Weise wird Ihre Komponente bei jeder Aktualisierung Ihrer Anzahl neu gerendert. Hoffentlich hilft das ein bisschen.
useState
. undefined
Wenn Sie dies lesen, denken Sie bitte daran, dass das Verlassen des zweiten Arguments dazu führt, dass Ihr Effekt bei jedem Rendern ausgelöst wird (wenn ich mich nicht irre).
Obwohl die akzeptierte Antwort funktioniert, wird sie nicht empfohlen. Wenn Sie mehr als einen Status haben und ihn mit useEffect verwenden, werden Sie gewarnt, ob Sie ihn dem Abhängigkeitsarray hinzufügen oder überhaupt nicht verwenden.
Es verursacht manchmal das Problem, das zu unvorhersehbaren Ausgaben führen kann. Ich schlage daher vor, dass Sie sich ein wenig Mühe geben, um Ihre Funktion als Klasse neu zu schreiben. Es gibt nur sehr wenige Änderungen, und Sie können einige Komponenten als Klasse und einige als Funktion haben. Sie sind nicht verpflichtet, nur eine Konvention zu verwenden.
Nehmen Sie das zum Beispiel
function App() {
const [appointments, setAppointments] = useState([]);
const [aptId, setAptId] = useState(1);
useEffect(() => {
fetch('./data.json')
.then(response => response.json())
.then(result => {
const apts = result.map(item => {
item.aptId = aptId;
console.log(aptId);
setAptId(aptId + 1);
return item;
})
setAppointments(apts);
});
}, []);
return(...);
}
und
class App extends Component {
constructor() {
super();
this.state = {
appointments: [],
aptId: 1,
}
}
componentDidMount() {
fetch('./data.json')
.then(response => response.json())
.then(result => {
const apts = result.map(item => {
item.aptId = this.state.aptId;
this.setState({aptId: this.state.aptId + 1});
console.log(this.state.aptId);
return item;
});
this.setState({appointments: apts});
});
}
render(...);
}
Dies ist nur zum Beispiel . Lassen Sie uns daher nicht über Best Practices oder potenzielle Probleme mit dem Code sprechen. Beide haben dieselbe Logik, aber die spätere funktioniert nur wie erwartet. Möglicherweise erhalten Sie die componentDidMount-Funktionalität, wenn useEffect für diese Zeit ausgeführt wird. Wenn Ihre App jedoch wächst, besteht die Möglichkeit, dass Sie auf einige Probleme stoßen. Anstatt in dieser Phase neu zu schreiben, ist es besser, dies in einem frühen Stadium zu tun.
Außerdem ist OOP nicht so schlecht, wenn prozedurorientierte Programmierung genug wäre, hätten wir niemals objektorientierte Programmierung gehabt. Es ist manchmal schmerzhaft, aber besser (technisch. Persönliche Probleme beiseite).
Es gibt keine componentDidMount
funktionalen Komponenten, aber React Hooks bieten eine Möglichkeit, das Verhalten mithilfe des Hooks zu emulieren useEffect
.
Übergeben Sie ein leeres Array als zweites Argument useEffect()
, um nur den Rückruf nur beim Mounten auszuführen.
Bitte lesen Sie die Dokumentation amuseEffect
.
function ComponentDidMount() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
console.log('componentDidMount');
}, []);
return (
<div>
<p>componentDidMount: {count} times</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
Click Me
</button>
</div>
);
}
ReactDOM.render(
<div>
<ComponentDidMount />
</div>,
document.querySelector("#app")
);
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
Sie möchten verwenden useEffect()
, was je nach Verwendung der Funktion genau wie componentDidMount () funktionieren kann.
Z.B. Sie können eine benutzerdefinierte loaded
Statuseigenschaft verwenden, die anfänglich auf false festgelegt ist, und beim Rendern auf true umschalten und den Effekt nur dann auslösen, wenn sich dieser Wert ändert.