Lecture notes and example code for Week 7 Day 3 lecture.
JavaScript
W7D3 - Side Effects & Other Data Fetching
To Do
Rules for Hooks
Pure Functions and Side Effects
useEffect
Dependencies
Cleanup
useEffect Flow
Two Rules for Hooks
Don't call Hooks inside loops, conditions, or nested functions. Always use Hooks at the top level of your React functions
Only call Hooks from React functions.
Pure Functions
A function is said to be pure if:
It produces no side-effects
It will return the same value if called with the same arguments
// simple pure functionsconstadd=(num1,num2)=>{returnnum1+num2;};constsayHello=(name)=>{return`Hello there ${name}!`;};
Side Effects
Any operation that modifies the state of the computer or interacts with something outside of your program is said to have a side effect
Common side effects:
Writing to standard out (eg. console.log)
Modifying the DOM directly (instead of relying on React)
Establishing socket connections (eg. ws or Socket.io)
Retrieving data from an API (eg. axios, jQuery, or the fetch API)
Setting timers or intervals
useEffect
useEffect is a Hook we can use to deal with side effects in our components
The effect hook fires after the browser has painted the DOM
Multiple effect hooks can be used inside of a single component to group similar operations together
constMyComponent=(props)=>{const[user,setUser]=useState({});useEffect(()=>{// retrieve user information from an API and update local state with the responsefetch(`/users/${props.userId}`).then(res=>res.json()).then(json=>setUser(json));});return(<divclassName="my-component"><p>You are logged in as {user.username}</p></div>);};
Dependencies
The second argument to useEffect is a dependency array that lets you specify when you want the hook to run
The hook will run again anytime the value of a dependency changes
NOTE: It is possible to get stuck in an infinite loop if the effect hook updates a value in the dependency array
If you want a useEffect hook to only run one time, pass it an empty dependency array ([])
// will run every time the value of user.firstName changesuseEffect(()=>{document.title=`${user.firstName}'s Home Page`;},[user.firstName]);// only runs onceuseEffect(()=>{fetch(`/users/${props.userId}`).then(res=>res.json()).then(json=>setUser(json));},[]);// infinite loop because it runs every time count gets updateduseEffect(()=>{setCount(count+1);},[count]);
Cleanup
Sometimes side effects need to be cleaned up (eg. socket connections terminated)
To perform cleanup, return a function from your useEffect
const[timer,setTimer]=useState(0);useEffect(()=>{// set up an interval to increment a timerconstmyInterval=setInterval(()=>{setTimer(timer=>timer+1);},1000);// declare a cleanup functionconstcleanup=()=>{clearInterval(myInterval);};returncleanup;},[]);
useEffect Flow
React turns your JSX into HTML (client-side rendering) and updates the DOM
The browser responds to the change by updating the UI
Any cleanup for effects from the previous render are performed