1669695400
Timestamps:
00:00 | Intro
01:46 | UseEffect and Component Lifecycle
12:33 | UseEffect vs React Query
1. Changing the Hooks Invocation Order
Hooks should not be called within loops, conditions, or nested functions since conditionally executed Hooks can cause unexpected bugs.
Avoiding such situations ensures that Hooks are called in the correct order each time the component renders. Also, it helps to keep the state of Hooks consistent across numerous useState
and useEffect
calls.
In the below example, I’ve created a basic React component to choose a person from the dropdown and displays the selected person’s data.
The SelectPerson component takes in the person’s id to be retrieved as a prop
and keeps the personal data in the state variable person
with the useEffect()
Hook.
import { useState, useEffect } from "react";
function SelectPerson({ id }) {
if (!id) {
return <div>Please Select a Person </div>;
}
const [person, setPerson] = useState({
name: "",
role: ""
});
useEffect(() => {
const selectPerson = async () => {
const response = await fetch(`/api/persons/${id}`);
const selectedPerson = await response.json();
setPerson(selectedPerson);
};
selectPerson();
}, [id]);
return (
<div>
<div>Name: {person.name}</div>
<div>Description: {person.role}</div>
</div>
);
}
export default function IndexPage() {
const [personId, setPersonId] = useState("");
return (
<div>
<select onChange={({ target }) => setPersonId(target.value)}>
<option value="">Select a person</option>
<option value="1">David</option>
<option value="2">John</option>
<option value="3">Tim</option>
</select>
<SelectPerson id={personId} />
</div>
);
}
At a glance, everything looks fine, but you will get a console error since useState()
, and useEffect()
are not available in every render.
To avoid this, you can simply move the return statement after the Hooks invocation.
So, always remember to use Hooks before any early returns at the top level of your React component.
import { useState, useEffect } from "react";
function SelectPerson({ id }) {
const [person, setPerson] = useState({
name: "",
role: ""
});
useEffect(() => {
const selectPerson = async () => {
const response = await fetch(`/api/persons/${id}`);
const selectedPerson = await response.json();
setPerson(selectedPerson);
};
if (id) {
selectPerson();
}
}, [id]);
if (!id) {
return 'Please Select a Person';
}
return (
<div>
<div>Name: {person.name}</div>
<div>Description: {person.role}</div>
</div>
);
}
....
...
...
2. Using useState when Re-Render is not Required
In functional components, you can use useState
Hook for state handling. Although it is pretty straightforward, there can be unexpected issues if it is not used correctly.
For example, assume a component with two buttons. The first button will trigger a counter, and the second button will make a request based on the current counter state.
import { useState } from "react";
function CounterCalc() {
const [counter, setCounter] = useState(0);
const onClickCounter = () => {
setCounter((c) => c + 1);
};
const onClickCounterRequest = () => {
apiCall(counter);
};
return (
<div>
<button onClick={onClickCounter}>Counter</button>
<button onClick={onClickCounterRequest}>Counter Request</button>
</div>
);
}
export default function IndexPage() {
return (
<div>
<CounterCalc />
</div>
);
}
The above component will work fine. But, since we didn’t use state
in the render phase, there will be unwanted re-renders each time the counter button clicks.
So, if you need to use a variable inside a component that preserves its state across renderings without triggering a re-render, useRef
Hook would be a better option.
import { useRef } from "react";
function CounterCalc() {
const counter = useRef(0);
const onClickCounter = () => {
counter.current++;
};
const onClickCounterRequest = () => {
apiCall(counter.current);
};
return (
<div>
<button onClick={onClickCounter}>Counter</button>
<button onClick={onClickCounterRequest}>Counter Request</button>
</div>
);
}
export default function IndexPage() {
return (
<div>
<CounterCalc />
</div>
);
}
3. Handling Actions via useEffect
The useEffect
Hook is one of the coolest methods for handling prop
or state
changes-related tasks. But, there can be situations where it makes things even more complex.
Suppose there is a component that takes a list of data and renders it to the DOM.
import { useState, useEffect } from "react";
function PersonList({ onSuccess }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [data, setData] = useState(null);
const fetchPersons = () => {
setLoading(true);
apiCall()
.then((res) => setData(res))
.catch((err) => setError(err))
.finally(() => setLoading(false));
};
useEffect(() => {
fetchPersons();
}, []);
useEffect(() => {
if (!loading && !error && data) {
onSuccess();
}
}, [loading, error, data, onSuccess]);
return <div>Person Data: {data}</div>;
}
export default function IndexPage() {
return (
<div>
<PersonList />
</div>
);
}
The first useEffect
Hook handles the apiCall()
on the initial render. If all the conditions are satisfied, the second useEffect
will call the onSuccess()
function.
However, there is no direct connection between the action and the invoked function. Therefore, we can’t guarantee that this scenario will only occur if the request is successful.
To handle such situations, we should move the onSucces()
function inside the apiCall()
function without using a separate Hook for that.
import { useState, useEffect } from "react";
function PersonList({ onSuccess }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [data, setData] = useState(null);
const fetchPersons = () => {
setLoading(true);
apiCall()
.then((fetchedPersons) => {
setData(fetchedPersons);
onSuccess();
})
.catch((err) => setError(err))
.finally(() => setLoading(false));
};
useEffect(() => {
fetchPersons();
}, []);
return <div>Person Data: {data}</div>;
}
export default function IndexPage() {
return (
<div>
<PersonList />
</div>
);
}
4. Using the Obsolete State
If you modify the useState
multiple times in subsequent lines in your code, the results might surprise you.
import { useState } from "react";
function Counter({ onSuccess }) {
const [count, setCount] = useState(0);
console.log(count);
const increaseCount = () => {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
};
return (
<>
<button onClick={increaseCount}>Increase</button>
<div>Counter: {count}</div>
</>
);
}
export default function IndexPage() {
return (
<div>
<Counter />
</div>
);
}
In the above example, the Counter
component increments the value of the state variable count
. Since increaseCount()
function calls the setCount()
function 3 times, you might think that one button click will increase the count
value by 3. But, it will only increment by 1 per button click.
The initial call to setCount(count + 1)
increase the count
appropriately, as count + 1 = 0 + 1 = 1. Similarly, the subsequent two calls of setCount(count + 1)
too set the count to 1 since it uses an obsolete state of the count
.
This happens because the value of the state will only be updated in the next render.
This obsolete state issue can be resolved by updating the state in a functional approach.
import { useState } from "react";
function Counter({ onSuccess }) {
const [count, setCount] = useState(0);
console.log(count);
const increaseCount = () => {
setCount(count => count + 1);
setCount(count => count + 1);
setCount(count => count + 1);
};
return (
<>
<button onClick={increaseCount}>Increase</button>
<div>Counter: {count}</div>
</>
);
}
export default function IndexPage() {
return (
<div>
<Counter />
</div>
);
}
5. Missing useEffect Dependencies
useEffect
Hook is one of the most used Hooks in React, and it always runs on each re-render by default. However, this behaviour of cleaning up or applying the effect after each render can cause performance issues.
We can avoid these unwanted renderings by passing a dependency array to useEffect Hook.
useEffect
Hook accepts dependency array as the second parameter, and it makes sure that effect will only run if the elements in the array are changed between re-renders.
useEffect(() => {
showCount(count);
}, [count]); // Only re-run the effect if count changes in the preceding render
Let’s consider the following example. It seems a well-working solution at a glimpse.
import { useState, useEffect} from "react";
function Counter() {
const [count, setCount] = useState(0);
const showCount = (count) => {
console.log("Show Count", count);
};
useEffect(() => {
showCount(count);
}, []);
return (
<>
<div>Hello..!!</div>
<div>Counter: {count}</div>
</>
);
}
export default function IndexPage() {
return (
<div>
<Counter />
</div>
);
}
But, there is an issue, and you can find the below warning in the DevTools console.
Note: Although it asks you to remove or keep the dependency array, you should not remove it since it will be a hack to trick React about dependencies.
To fix this the correct way, you need to ensure the array contains all the dependency values within the component scope that might vary with time and are used by the effect
.
Otherwise, your code will use values from prior renderings that are no longer valid.
import { useState, useEffect} from "react";
function Counter() {
const [count, setCount] = useState(0);
const showCount = (count) => {
console.log("Show Count", count);
};
useEffect(() => {
showCount(count);
}, [count]);
return (
<>
<div>Hello..!!</div>
<div>Counter: {count}</div>
</>
);
}
export default function IndexPage() {
return (
<div>
<Counter />
</div>
);
}
Final Thoughts
React Hooks are reusable, clean, and simple functions that can be incorporated into your workflow. In addition, they offer us many options for a diverse range of uses, so we don’t have to build them from scratch.
But, developers tend to make some significant mistakes when using React Hooks with advanced and custom features. In this article, I discussed 5 such common mistakes developers should avoid when using React Hooks.
I hope you will use them in your next React project and if you have any suggestions, please share them in the comments section.
Thank you for Reading !!!
#reactjs #react
1598839687
If you are undertaking a mobile app development for your start-up or enterprise, you are likely wondering whether to use React Native. As a popular development framework, React Native helps you to develop near-native mobile apps. However, you are probably also wondering how close you can get to a native app by using React Native. How native is React Native?
In the article, we discuss the similarities between native mobile development and development using React Native. We also touch upon where they differ and how to bridge the gaps. Read on.
Let’s briefly set the context first. We will briefly touch upon what React Native is and how it differs from earlier hybrid frameworks.
React Native is a popular JavaScript framework that Facebook has created. You can use this open-source framework to code natively rendering Android and iOS mobile apps. You can use it to develop web apps too.
Facebook has developed React Native based on React, its JavaScript library. The first release of React Native came in March 2015. At the time of writing this article, the latest stable release of React Native is 0.62.0, and it was released in March 2020.
Although relatively new, React Native has acquired a high degree of popularity. The “Stack Overflow Developer Survey 2019” report identifies it as the 8th most loved framework. Facebook, Walmart, and Bloomberg are some of the top companies that use React Native.
The popularity of React Native comes from its advantages. Some of its advantages are as follows:
Are you wondering whether React Native is just another of those hybrid frameworks like Ionic or Cordova? It’s not! React Native is fundamentally different from these earlier hybrid frameworks.
React Native is very close to native. Consider the following aspects as described on the React Native website:
Due to these factors, React Native offers many more advantages compared to those earlier hybrid frameworks. We now review them.
#android app #frontend #ios app #mobile app development #benefits of react native #is react native good for mobile app development #native vs #pros and cons of react native #react mobile development #react native development #react native experience #react native framework #react native ios vs android #react native pros and cons #react native vs android #react native vs native #react native vs native performance #react vs native #why react native #why use react native
1607768450
In this article, you will learn what are hooks in React JS? and when to use react hooks? React JS is developed by Facebook in the year 2013. There are many students and the new developers who have confusion between react and hooks in react. Well, it is not different, react is a programming language and hooks is a function which is used in react programming language.
Read More:- https://infoatone.com/what-are-hooks-in-react-js/
#react #hooks in react #react hooks example #react js projects for beginners #what are hooks in react js? #when to use react hooks
1607399166
While coding this week, I had to convert one of my class components in React to a functional component.
Why would I need to do that? After all, the parent component sees the two types of components as identical. Sure, functional components can be shorter, require less boilerplate, and maybe even perform better. But that’s not why I needed to do it. I was using an npm package that had React hooks and hooks are for functional components only. React Hooks, added in React 16.8, allow functional components to manage state and replace lifecycle methods. To use the hook I needed I had to convert my class components to a functional.
Here are the steps I followed to change my class component to a functional component:
#react-hook-useeffect #useeffect #react-hook #react-hook-usestate #react
1599277908
Validating inputs is very often required. For example, when you want to make sure two passwords inputs are the same, an email input should in fact be an email or that the input is not too long. This is can be easily done using React Hook From. In this article, I will show you how.
The most simple, yet very common, validation is to make sure that an input component contains input from the user. React Hook Form basic concept is to register input tags to the form by passing register() to the tag’s ref attribute. As we can see here:
#react-native #react #react-hook-form #react-hook
1590324000
It’s been a while since React v16.8 has been released. One of the most important features that was added to React with this release was the mighty hooks. With hooks you can turn the dumb state-less components to smart state-full components. Hooks are incredible but they for sure have changed the way we as developers need to think about the components. One thing I have seen a lot of developers struggle with is the useEffect hook. This one hook alone can somewhat replace the good old life cycle methods that were accessible with class-full components. This article of mine is an attempt at imitating some of the life-cycle methods with useEffect hook and hopefully give you an idea of how to use it accordingly
#useeffect #react-hook #react #react-native