Lassen Sie mich das Ergebnis dieses Codes erklären, damit ich mein Problem leicht stellen kann.
const ForExample = () => {
const [name, setName] = useState('');
const [username, setUsername] = useState('');
useEffect(() => {
console.log('effect');
console.log({
name,
username
});
return () => {
console.log('cleaned up');
console.log({
name,
username
});
};
}, [username]);
const handleName = e => {
const { value } = e.target;
setName(value);
};
const handleUsername = e => {
const { value } = e.target;
setUsername(value);
};
return (
<div>
<div>
<input value={name} onChange={handleName} />
<input value={username} onChange={handleUsername} />
</div>
<div>
<div>
<span>{name}</span>
</div>
<div>
<span>{username}</span>
</div>
</div>
</div>
);
};
Wenn die ForExample component
Reittiere aktiviert sind, wird der Effekt protokolliert. Dies hängt mit dem zusammen componentDidMount()
.
Und wenn ich die Namenseingabe ändere, werden sowohl "Effekt" als auch "Bereinigt" protokolliert. Umgekehrt wird keine Nachricht protokolliert, wenn ich die Eingabe des Benutzernamens ändere, seit ich [username]
den zweiten Parameter von hinzugefügt habe useEffect()
. Dies hängt mit dem zusammencomponentDidUpdate()
Zuletzt wird beim ForExample component
Aufheben der Bereitstellung "bereinigt" protokolliert. Dies hängt mit dem zusammen componentWillUnmount()
.
Wir alle wissen das.
Zusammenfassend wird "bereinigt" immer dann aufgerufen, wenn die Komponente neu gerendert wird (einschließlich Unmount).
Wenn ich möchte, dass diese Komponente nur für den Moment "bereinigt" protokolliert wird, in dem sie nicht gemountet ist, muss ich nur den zweiten Parameter von useEffect()
in ändern []
.
Wenn ich jedoch zu wechsle [username]
, []
wird ForExample component
die componentDidUpdate()
Eingabe für den Namen nicht mehr implementiert .
Was ich tun möchte, ist, dass die Komponente sowohl componentDidUpdate()
nur für die Namenseingabe als auch unterstützt componentWillUnmount()
. (Protokollierung 'bereinigt' nur für den Moment, in dem die Komponente abgemeldet wird)
quelle
username
zweiten Argument enthält, und eine, die ein leeres Array als zweites Argument erhält.Antworten:
Da die Bereinigung nicht von der abhängig ist
username
, können Sie die Bereinigung in einem separaten BereichuseEffect
ablegen, dem als zweites Argument ein leeres Array zugewiesen wird.Beispiel
const { useState, useEffect } = React; const ForExample = () => { const [name, setName] = useState(""); const [username, setUsername] = useState(""); useEffect( () => { console.log("effect"); }, [username] ); useEffect(() => { return () => { console.log("cleaned up"); }; }, []); const handleName = e => { const { value } = e.target; setName(value); }; const handleUsername = e => { const { value } = e.target; setUsername(value); }; return ( <div> <div> <input value={name} onChange={handleName} /> <input value={username} onChange={handleUsername} /> </div> <div> <div> <span>{name}</span> </div> <div> <span>{username}</span> </div> </div> </div> ); }; function App() { const [shouldRender, setShouldRender] = useState(true); useEffect(() => { setTimeout(() => { setShouldRender(false); }, 5000); }, []); return shouldRender ? <ForExample /> : null; } ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div>
quelle
Sie können mehr als einen useEffect verwenden
Wenn meine Variable beispielsweise data1 ist, kann ich all dies in meiner Komponente verwenden
useEffect( () => console.log("mount"), [] ); useEffect( () => console.log("will update data1"), [ data1 ] ); useEffect( () => console.log("will update any") ); useEffect( () => () => console.log("will update data1 or unmount"), [ data1 ] ); useEffect( () => () => console.log("unmount"), [] );
quelle
function LegoComponent() { const [lego, setLegos] = React.useState([]) React.useEffect(() => { let isSubscribed = true fetchLegos().then( legos=> { if (isSubscribed) { setLegos(legos) } }) return () => isSubscribed = false }, []); return ( <ul> {legos.map(lego=> <li>{lego}</li>)} </ul> ) }
Im obigen Code gibt die Funktion fetchLegos ein Versprechen zurück. Wir können das Versprechen „stornieren“, indem wir eine Bedingung für den Anwendungsbereich haben, die verhindert, dass die App den Status festlegt, nachdem die Komponente nicht bereitgestellt wurde.
quelle
useEffect sind in ihrem eigenen Bereich isoliert und werden entsprechend gerendert. Bild von https://reactjs.org/docs/hooks-custom.html
quelle
Anstatt zu viele komplizierte Funktionen und Methoden zu erstellen, erstelle ich einen Ereignis-Listener und lasse das Ein- und Aushängen automatisch für mich durchführen, ohne dass ich mich manuell darum kümmern muss. Hier ist ein Beispiel.
//componentDidMount useEffect( () => { window.addEventListener("load", pageLoad); //component will unmount return () => { window.removeEventListener("load", pageLoad); } });
Jetzt, da dieser Teil fertig ist, führe ich einfach alles aus, was ich will, über die Funktion pageLoad wie folgt.
const pageLoad = () =>{ console.log(I was mounted and unmounted automatically :D)}
quelle