Med React 16.8 (6 februari 2019) kom möjligheten att använda hooks i komponenter som inte är en class, alltså funktionella komponenter. Men hur fungerar egentligen React hooks?
Läser du dokumentationen (https://react.dev/reference/react) presenteras tidigt två typer av hooks: State Hook och Effect Hook. Är du van vid att koda React-komponenter som klasser är det här den enklaste förklaringen, som vi ser det:
State Hook (useState) innefattar: State och setState.
Effect Hook (useEffect) innefattar: Alla lifecycle methods.
I följande exempel har vi en funktionell React-komponent, alltså inte en class, som importerar useState och useEffect.
import { useState, useEffect } from 'react'; import axios from 'axios'; const FunctionBasedComponent = () => { const [ searchResult, setSearchResult ] = useState([]); const [ query, setQuery ] = useState([]); const doSearch = async () => { const response = await axios. get(`http://website.se/search?query=${query}`); setSearchResult(response.data); }; useEffect( () => { doSearch() }, [query]); return( //Markup for searching <></> ); } export default FunctionBasedComponent;
useState initieras genom att du i en array skickar in ett variabelnamn (searchResult) och en funktion (setSearchResult) som ändrar variabeln.
const [ searchResult, setSearchResult ] = useState([]);
searchResult har i det här fallet inget initialt värde, men du kan också initiera useState med ett värde till din variabel.
const [ searchResult, setSearchResult ] = useState(['Activator']);
Funktionen doSearch() hämtar data genom ett API-anrop. Resultatet skickas som argument till setSearchResult, som i sin tur ger variabeln searchResult ett nytt värde.
const doSearch = async () => { const response = await axios.get(`http://website.se/search?query=${query}`); setSearchResult(response.data); };
Vad är då rollen för useEffect i det här? Precis som med componentDidMount anropas funktionen i useEffect (i det här fallet doSearch()) så fort komponenten laddas. Den anropas också så fort komponenten uppdateras, som med componentDidUpdate.
useEffect( () => { doSearch() });
I exemplet ovan får vi dock problem i form av en evighetsloop. Funktionen doSearch() använder nämligen setSearchResult, som uppdaterar komponentens state. Det triggar i sin tur useEffect om och om igen.
useEffect( () => { doSearch(searchResult), [] });
Effect Hook kan göras beroende av något för att köras. För att lösa problemet ovan skickar vi in en tom array som andra argument till useEffect. Nu körs useEffect bara en gång, när komponenten laddas, eftersom den är beroende av något som aldrig kan ändras.
useEffect( () => { doSearch() }, [query]);
I exemplet ovan är useEffect i stället beroende av state-variabeln query. Så fort query ändras körs useEffect. Det passar bra om du till exempel vill söka i realtid.
React hooks gör komponenterna slimmade och därmed mer lättöverskådliga. I exemplet vi har gått igenom har vi byggt en funktion för att söka efter data med kort och koncis kod.
import { useState, useEffect } from 'react'; import axios from 'axios'; const FunctionBasedComponent = () => { const [ searchResult, setSearchResult ] = useState([]); const [ query, setQuery ] = useState([]); const doSearch = async () => { const response = await axios. get(`http://website.se/search?query=${query}`); setSearchResult(response.data); }; useEffect( () => { doSearch() }, [query]); return( //Markup for searching <></> ); } export default FunctionBasedComponent;
