ReactJS Redux-Saga and Redux Thunk Questions to Crack the Interview. I compiled a list of react js, redux, and redux-thunk interview questions, a few of which I encountered during my journey and a few of which I found on Google and prepared to answer. Learn About the Top Asked Interview Questions on ReactJS Redux-Saga and Redux Thunk Interview Questions Set-2 and more About React development.
For Set-1 Top ReactJS Redux-Saga and Redux Thunk Interview Questions Set-1 Visit Here for Top Interview Questions Set-1
Important Questions in Reactjs, Redux, and Redux Thunk
- Which types of components have you worked with and explain them? 2. Differences between functional and class-based components.
- Differences between controlled and uncontrolled components.
- Explain Redux Architecture.
- Can we use the redux state or store it inside the plain javascript function if yes how?
- Explain about Higher order components.
- Is it mandatory to give the same parameter name (mapStateToProps and mapDispatchToProps) to the connect() function?
- Ex - A particular web application is very slow. How can you increase its performance?
- Have you done any unit testing in your ReactJS application?
- Explain Ajax.
- Explain how we can achieve authentication/authorization in Axios.
- Explain about web pack.
- Can we use multiple middlewares in redux?
- Is redux asynchronous or synchronous? Or will it become asynchronous only on the usage of middlewares (redux-saga, etc)
- Explain how data can be passed from parent to child and vice versa.
- Difference between state and props.
- How do you handle API synchronously?
- What is a Storybook?
- Can you create multiple stores, if you can, how would you access the store variable?
- Can you create multiple reducers?
- When you click on a button multiple times what does the API return?
- How have you handled API calls in your application?
- How will you combine the reducers?
- How can you access the variable/data in one reducer from another reducer?
1. Explain React hooks. Explain at least 3 hooks in ReactJS?
-
useState:
- Purpose: Used to add state to functional components.
- Usage: Returns an array with the current state value and a function to update it. You can also provide an initial state.
- Example:
const [count, setCount] = useState(0);
-
useEffect:
- Purpose: Performs side effects in functional components. Similar to
componentDidMount
,componentDidUpdate
, andcomponentWillUnmount
in class components. - Usage: Accepts a function that contains imperative, possibly effectful code.
- Example:
useEffect(() => { // Side effect code here return () => { // Cleanup code (optional) }; }, [dependency]);
- Purpose: Performs side effects in functional components. Similar to
-
useContext:
- Purpose: Allows functional components to subscribe to a context without introducing nesting.
- Usage: Accepts a context object (created with
React.createContext
) and returns the current context value. - Example:
const contextValue = useContext(MyContext);
Additional Hooks:
-
useReducer:
- Purpose: An alternative to
useState
for managing more complex state logic. - Usage: Takes a reducer function and initial state, returns the current state and a dispatch function.
- Example:
const [state, dispatch] = useReducer(reducer, initialState);
- Purpose: An alternative to
-
useCallback:
- Purpose: Memoizes a callback function, preventing it from being recreated on every render.
- Usage: Takes a callback and an array of dependencies. Returns a memoized version of the callback.
- Example:
const memoizedCallback = useCallback(() => { // Callback logic }, [dependency]);
-
useMemo:
- Purpose: Memoizes the result of a function, preventing unnecessary recalculations.
- Usage: Takes a function and an array of dependencies. Returns the memoized result of the function.
- Example:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
-
useRef:
- Purpose: Creates a mutable object that persists across renders and doesn't trigger re-renders when changed.
- Usage: Returns a mutable object with a
current
property. - Example:
const myRef = useRef(initialValue);
-
useImperativeHandle:
- Purpose: Customizes the instance value that is exposed when using
React.forwardRef
. - Usage: Takes a ref object and a callback to customize the value.
- Example:
useImperativeHandle(ref, () => ({ // Custom methods or values }), [dependencies]);
- Purpose: Customizes the instance value that is exposed when using
-
useLayoutEffect:
- Purpose: Similar to
useEffect
, but fires synchronously after all DOM mutations. - Usage: Useful for measurements or DOM manipulations that need to be applied before the user sees the changes.
- Example:
useLayoutEffect(() => { // DOM manipulations return () => { // Cleanup code (optional) }; }, [dependency]);
- Purpose: Similar to
-
useDebugValue:
- Purpose: Enables custom display names and labels for custom hooks in React DevTools.
- Usage: Takes a single argument (e.g., a label or formatter function).
- Example:
useDebugValue(value);
These hooks are fundamental to building powerful and efficient React applications by managing state, side effects, and optimization.
2. Explain About the useCallback and useMemo
USEMEMO
Returns a memoized value.
- The useMemo Hook only runs when one of its dependencies is updated.
- This can improve performance.
- Think of memoization as caching a value so that it does not need to be recalculated.
- The useMemo and useCallback Hooks are similar. The main difference is that useMemo returns a memoized value and useCallback returns a memoized function.
Use useMemo
- To fix this performance issue, we can use the useMemo Hook to memoize the expensiveCalculation function. This will cause the function to only run when needed.
- We can wrap the expensive function call with useMemo.
- The useMemo Hook accepts a second parameter to declare dependencies. The expensive function will only run when its dependencies have changed.
In the following example, the expensive function will only run when the count is changed and not when todos are added.
Example
import { useState, useMemo } from "react"; import ReactDOM from "react-dom"; const App = () => { const [count, setCount] = useState(0); const [todos, setTodos] = useState([]); const calculation = useMemo(() => expensiveCalculation(count), [count]); const increment = () => { setCount((c) => c + 1); }; const addTodo = () => { setTodos((t) => [...t, "New Todo"]); }; return ( <div> <div> <h2>My Todos</h2> {todos.map((todo, index) => { return <p key={index}>{todo}</p>; })} <button onClick={addTodo}>Add Todo</button> </div> <hr /> <div> Count: {count} <button onClick={increment}>+</button> <h2>Expensive Calculation</h2> {calculation} </div> </div> ); }; const expensiveCalculation = (num) => { console.log("Calculating..."); for (let i = 0; i < 1000000000; i++) { num += 1; } return num; }; ReactDOM.render(<App />, document.getElementById(`root`));
- Pass a “create” function and an array of dependencies. useMemo will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.
- Remember that the function passed to useMemo runs during rendering. Don’t do anything there that you wouldn’t normally do while rendering. For example, side effects belong in useEffect, not useMemo.
React useEffect Hooks
- The useEffect Hook allows you to perform side effects in your components.
- Some examples of side effects are: fetching data, directly updating the DOM, and timers.
- useEffect accepts two arguments. The second argument is optional.
useEffect(<function>, <dependency>)
useEffect(() => { setTimeout(() => { setCount((count) => count + 1); }, 1000); }, []);
3. What are a spread operator and a Rest Operator? Whether it makes a shallow copy or a deep copy?
The spread operator allows an iterable to expand in places where 0+ arguments are expected. It is mostly used in the variable array where more than 1 value is expected. It allows us the privilege to obtain a list of parameters from an array. The syntax of the Spread operator is the same as the Rest parameter but it works the opposite of it.
Syntax:
var variablename1 = [...value];
In the above syntax, … is a spread operator which will target all values in a particular variable. When … occurs in the function call or alike, it`s called a spread operator. Spread operator can be used in many cases, like when we want to expand, copy,concat, with math object. Let’s look at each of them one by one:
Rest parameters
The rest parameter syntax allows a function to accept an indefinite number of arguments as an array, providing a way to represent variadic functions in JavaScript.
function myFun(a, b, ...manyMoreArgs) { console.log("a", a) console.log("b", b) console.log("manyMoreArgs", manyMoreArgs) } myFun("one", "two", "three", "four", "five", "six")
4. How to increase performance in ReactJS to Load the Pages fast?
- Function/Stateless Components and React.PureComponent
- Using Production Mode Flag in Webpack
- Use React. Fragments to Avoid Additional HTML Element Wrappers
- Avoid Inline Function Definition in the Render Function.
- Avoiding Props in the Initial States
- Avoid Async Initialization in componentWillMount()
- Memoize React Components
- Using a CDN
- Enable Gzip Compression on Web Server
- Consider Server-side Rendering
5. Explain the Webpack and how to implement the Webpack in the reactJS ?
Webpack is a popular module bundling system built on top of Node. js. It can handle not only the combination and minification of JavaScript and CSS files but also other assets such as image files (spriting) through the use of plugins.
webpack.config.js
const path = require("path"); const webpack = require("webpack"); module.exports = { entry: { app: "./entry.js" }, // Start bundling output: { path: path.join(__dirname, "dist"), // Output to dist directory filename: "[name].js", // Emit app.js by capturing entry name }, // Resolve encountered imports module: { rules: [ { test: /.css$/, use: ["style-loader", "css-loader"] }, { test: /.js$/, use: "swc-loader", exclude: /node_modules/ }, ], }, // Perform additional processing plugins: [new webpack.DefinePlugin({ HELLO: "hello" })], // Adjust module resolution algorithm resolve: { alias: { react: "preact-compat" } }, };
How to Remove files in WebPack
exclude: /node_modules/,
6. What is CORS? Explain? And How to Handle Cors Error in the ReactJS?
- CORS stands for cross-origin resource sharing. Just like HTTPS, it`s a protocol that defines some rules for sharing resources from a different origin.
- We know that modern web apps consist of two key components: a client and a server. The client requests some data from the server, and the server sends back data as a response.
Enter CORS
CORS enables you to access a resource from a different origin. It is used to override your browser`s default behavior due to SOP. So now when your client requests a resource, the response will additionally contain a stamp that tells your browser to allow resource sharing across different origins.
How to Solve the Cors Error In React JS
I have a function makeAPICall that is invoked when our <App> component mounts on the DOM. Inside the makeAPCall function, I make a GET request to the endpoint http://localhost:8080/ using the Fetch API.
If you open the browser and check your console, instead of the response from the endpoint you`ll see an error that looks like this:
CORS error.
The above is the typical CORS error that occurs because your browser is blocking requests to your server. Even though both your client and the server are running from localhost, your server is hosted on port 8080 and your React client on port 3000. Therefore, both have a different origin, and the browser`s SOP policy comes into play. Let`s dive deeper into this CORS error and see a server-side solution to fix this problem.
CORS Should Always Be Handled From the Server Side!
- Let`s have a closer look at the above CORS error.
- Access to fetch at `http://localhost:8080/` from origin `http://localhost:3000`
- has been blocked by CORS policy: No `Access-Control-Allow-Origin` header is
- present on the requested resource. If an opaque response serves your needs,
- set the request`s mode to `no-cors` to fetch the resource with CORS disabled.
It states that there`s a missing Access-Control-Allow-Origin header on the resource you requested. If you think about it, your client doesn`t have anything to do with CORS. It`s only something that your browser imposes, and it suggests that your requested resource should be configured differently.
Therefore, it makes sense to configure the response from the server in such a way that the browser identifies this as a CORS request. Hence, logically, CORS should always be handled from the server side. Later we`ll explore a way to work around this on the client-side, but the most reliable solution is to always make the response from the server CORS-friendly.
Enable CORS on the Server Side
Let`s head back to our server`s app.js file.
app.get(`/cors`, (req, res) => { res.set(`Access-Control-Allow-Origin`, `*`); res.send({ "msg": "This has CORS enabled ?" }) })
Inside the request middleware callback, I first set the Access-Control-Allow-Origin header to an asterisk. The asterisk indicates that this resource can be requested by any client. Let`s also change the endpoint in our React app.
const response = await fetch(`http://localhost:8080/cors`, { mode: `cors` });
CORS enabled.
Notice that the CORS error goes away and that you get back the response along with some JSON data. Everything works as intended. Great! All you needed to do was to attach that CORS stamp to your response. Note that you may need to restart your back-end server to see the above changes in action.
You can also set the Access-Control-Allow-Origin to specific domains instead of the asterisk. For instance, setting it to http://localhost:3000 will only enable CORS for clients that are running on the specified URL, localhost:3000.
app.get(`/cors`, (req, res) => { res.set(`Access-Control-Allow-Origin`, `http://localhost:3000`); res.send({ "msg": "This has CORS enabled ?" }) })
While the server-side fix to CORS is the most technically coherent solution to this problem, there`s a small catch. It requires you to make modifications on the server-side. In some cases, you might not have access to server-side code.
For example, if you`re using a third-party service for authentication, notification, sending emails, etc., you might run into this problem. In such cases, there isn`t much you can do but shoot an email to the developers asking them to enable CORS for your app. There`s a neat trick specific to React apps that you can use to work around this problem. Let`s see how it works.
7. How does Redux Work and Explain the Full architecture of Redux and ReactJS?
How Redux works
The way Redux works is simple. There is a central store that holds the entire state of the application. Each component can access the stored state without having to send down props from one component to another.
There are three building parts: actions, store, and reducers.
Actions in Redux
- Simply put, actions are events. They are the only way you can send data from your application to your Redux store. The data can be from user interactions, API calls, or even form submissions.
- Actions are sent using the store.dispatch() method. Actions are plain JavaScript objects, and they must have a type property to indicate the type of action to be carried out.
- They must also have a payload that contains the information that should be worked on by the action. Actions are created via an action creator.
Here’s an example of an action that can be carried out during login in an app:
const setLoginStatus = (name, password) => { return { type: "LOGIN", payload: { username: "foo", password: "bar" } } }
Reducers in Redux
- Reducers are pure functions that take the current state of an application, perform an action, and return a new state. These states are stored as objects, and they specify how the state of an application changes in response to an action sent to the store.
- It is based on the reduce function in JavaScript, where a single value is calculated from multiple values after a callback function has been carried out.
const LoginComponent = (state = initialState, action) => { switch (action.type) { // This reducer handles any action with type "LOGIN" case "LOGIN": return state.map(user => { if (user.username !== action.username) { return user; } if (user.password == action.password) { return { ...user, login_status: "LOGGED IN" } } }); default: return state; } };
- Reducers take the previous state of the app and return a new state based on the action passed to it.
- As pure functions, they do not change the data in the object passed to them or perform any side effects in the application. Given the same object, they should always produce the same result.
Store in Redux
The store holds the application state. It is highly recommended to keep only one store in any Redux application. You can access the state stored, update the state, and register or unregister listeners via helper methods.
Let’s create a store for our login app:
const store = createStore(LoginComponent);
Actions performed on the state always return a new state. Thus, the state is very easy and predictable.
Now that we know a little more about Redux, let’s go back to our login component example that was implemented earlier and see how Redux can improve the component.
class App extends React.Component { render() { return ( <div> <Status user={this.props.user.name}/> <Login login={this.props.setLoginStatus}/> </div> ) } }
- With Redux, there’s one general state in the store, and each component has access to the state.
- This eliminates the need to continuously pass state from one component to another. You can also select the slice from the store for a particular component; this makes your app more optimized.
Why use Redux?
- When using Redux with React, states will no longer need to be lifted up. This makes it easier for you to trace which action causes any change.
- As you can see in the example above, the component does not need to provide any state or method for its children components to share data among themselves. Everything is handled by Redux. This greatly simplifies the app and makes it easier to maintain.
- This is the primary reason why you should use Redux, but it’s not the only benefit. Take a look at the list below for a summary of what you stand to gain by using Redux for state management.
Redux makes the state predictable
- In Redux, the state is always predictable. If the same state and action are passed to a reducer, the same result is always produced because reducers are pure functions. The state is also immutable and is never changed. This makes it possible to implement arduous tasks like infinite undo and redo.
- It is also possible to implement time travel — that is, the ability to move back and forth between the previous states and view the results in real-time.
Redux is maintainable
- Redux is strict about how code should be organized, which makes it easier for someone with knowledge of Redux to understand the structure of any Redux application. This generally makes it easier to maintain. This also helps you segregate your business logic from your component tree. For large-scale apps, it’s critical to keep your app more predictable and maintainable.
Debugging is easy in Redux
- Redux makes it easy to debug an application. By logging actions and states, it is easy to understand coding errors, network errors, and other forms of bugs that might come up during production.
- Besides logging, it has great DevTools that allow you to time-travel actions, persist actions on page refresh, etc. For medium- and large-scale apps, debugging takes more time than actually developing features. Redux DevTools makes it easy to take advantage of all Redux has to offer.
Performance Benefits
- You might assume that keeping the app’s state global would result in some performance degradation. To a large extent, that’s not the case.
- React Redux implements many performance optimizations internally so that your connected component only rerenders when it needs to.
Ease of testing
- It is easy to test Redux apps since functions are used to change the state of pure functions.
State persistence
- You can persist some of the app’s state to local storage and restore it after a refresh. This can be nifty.
Server-side rendering
- Redux can also be used for server-side rendering. With it, you can handle the initial render of the app by sending the state of an app to the server along with its response to the server request. The required components are then rendered in HTML and sent to the clients.
Example Explain
- An Input Field is filled with the text ‘Buy Food’
- This Data is gathered when the Submit button is hit
- The Data is then passed into an Action that’s Dispatched to the Reducer
- The Reducer reads the Action and Determines what to do with the value
- The Reducer adds it to the toDos array within the initial state
- The State is then returned
8. Difference between find and filter array methods
- The find() method is used to find all the descendant elements of the selected element. It finds the element in the DOM tree by traversing through the root to the leaf.
- The filter() method is used to filter all the elements and return the element that matches and the elements that do not match are removed.
- The only difference is the filter() method searches through all the elements while the find() method searches through all the child elements only.
- The find() method returns the first value that matches the collection. Once it matches the value in the findings, it will not check the remaining values in the array collection.
- The filter() method returns the matched values in an array from the collection. It will check all values in the collection and return the matched values in an array.
- The find() method doesn’t work in IE <= 11. The filter() method works in all browsers, including IE9+.
- From the collection of filter() method results, you can get the first matched value using the below snippet. This method overcomes the IE combability issue of the find() method.
9. Explain how do you manage the store in redux?
import React from `react`; import ReactDOM from `react-dom`; import `./index.css`; import App from `./components/App/App`; import * as serviceWorker from `./serviceWorker`; import { Provider } from `react-redux`; import { createStore } from `redux`; const store = createStore(() => ({ birds: [ { name: `robin`, views: 1 } ] })); ReactDOM.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode>, document.getElementById(`root`) ); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA serviceWorker.unregister(); import React from `react`; import { useSelector } from `react-redux`; import `./App.css`; function App() { const birds = useSelector(state => state.birds); return <></> } export default App;
10. What is Redux-Saga?
- Redux Saga is also a middleware library that helps us with API calls or side effects. Redux Saga uses an ES6 feature called ‘Generators’ which helps us to write asynchronous code.
- Generators are the functions that came with ECMA Script 6. And the amazing part is that the generator functions can be paused in between the execution or even can be exited and later re-entered.
- A generator function is represented as function* functionName() {}
- With ES6, we have been introduced with a special type of function called generators. With generators, the functions can be paused in the middle multiple times and resumed later which allows other codes to run in between.
- Inside the generator function, we use a special keyword called yield which is used to pause the function inside itself.
11. Once logged in to the application, and you do nothing for the next 10 mins, what happens? Does the application get logged out? If yes/no, how are you managing those?
What is Idle Timeout
- Idle timeout is the amount of time the user or client remains inactive on the web application. This is the time that the user doesn’t do anything on the app or away from the computer. It is typical for high-risk web apps to have 2–5 minutes of idle time and low-risk web apps to have 15–30 minutes of idle time before logging out the user.
Why do we need it?
- In most cases, we need an idle timeout in the web apps for security reasons and to avoid unnecessary calls to the API. The web app is vulnerable to security attacks. The longer it is idle, the more time for the attacker to inject some malicious code or hijack the session.
- In another case, imagine a scenario where there are calls to be made to the backend API for every 30 sec or 1 min to retrieve the updated data. There is no need to make those calls if the user is away from the computer. We can avoid these unnecessary calls with the idle timeout feature.
Here are the libraries used for this project.
- react-bootstrap for the UI
- react-idle-timer for the idle timeout
How To Find Out User is Idle
We are using the library called ng-idle But, I want to show how we can detect the user is idle without any libraries. We have Keyboard events and mouse events from the DOM API which we can use to detect if the users are idle or not. When there are no mouse or keyboard events fired, we can conclude that the user is idle.
Implementation
Let’s see how we can implement the idle timeout feature in the React application with the react-idle-timer library. As a first step, we need to install react-idle-timer dependencies in the existing application.
npm i react-idle-timer --save
Once installed we have to import these modules in the Layout.js file
import React from `react` import { Switch, Route } from `react-router-dom` import IdleTimer from `react-idle-timer`; import { DashboardPage } from `./dashboard/Dashboard` import PropTypes from `prop-types`; import `bootstrap/dist/css/bootstrap.min.css`; import `./App.css` class Layout extends React.Component { constructor(props){ super(props) this.state = { timeout:1000 * 5 * 1, showModal: false, userLoggedIn: false, isTimedOut: false } this.idleTimer = null this.onAction = this._onAction.bind(this) this.onActive = this._onActive.bind(this) this.onIdle = this._onIdle.bind(this) } _onAction(e) { console.log(`user did something`, e) this.setState({isTimedOut: false}) } _onActive(e) { console.log(`user is active`, e) this.setState({isTimedOut: false}) } _onIdle(e) { console.log(`user is idle`, e) const isTimedOut = this.state.isTimedOut if (isTimedOut) { this.props.history.push(`/`) } else { this.setState({showModal: true}) this.idleTimer.reset(); this.setState({isTimedOut: true}) } } render(){ const { match } = this.props return( <> <IdleTimer ref={ref => { this.idleTimer = ref }} element={document} onActive={this.onActive} onIdle={this.onIdle} onAction={this.onAction} debounce={250} timeout={this.state.timeout} /> <div className=""> <Switch> <Route exact path={`${match.path}dashboard`} render={(props) => <DashboardPage {...props} /> }/> /> </Switch> </div> </> ) } } Layout.propTypes = { match: PropTypes.any.isRequired, history: PropTypes.func.isRequired } export default Layout
12. Once logged in to the application, do you display a success message?
Yes
import { store } from "react-notifications-component"; store.addNotification({ title: "Success", message: "Login successful", type: "success", container: "top-center", animationIn: ["animated", "fadeIn"], animationOut: ["animated", "fadeOut"], dismiss: { duration: 2000, }, });
13. From where do you check whether the entered login credentials are correct?
onSubmit = (e) => { e.preventDefault(); axios.get(`API_PATH`) .then(res => { const user = res.data[0].username; const password = res.data[0].password; const username = this.state.username; const passwordEntered = this.state.password; if(username === `` && passwordEntered === ``){ document.getElementById(`status`).innerHTML = `<p>Please Enter A Valid Username and Password</p>`; }else if(user === username && passwordEntered === password){ document.getElementById(`status`).innerHTML = ``; console.log(user, password) }else{ document.getElementById(`status`).innerHTML = `<p>Please Enter A Valid Username and Password</p>`; } }) .catch(error => { console.log(error); }); }
SAGA
submitClick = () => { const { email, password } = this.state; let payload = { email: email, password: password, }; if (this.validateFields()) { this.props.UserAction.login(payload); } };
SAGA
if (result) { // console.log(result) localStorage.setItem("id", result.data.user.id); }
Reducer
const INITIAL_STATE = { CurrentUser: [], isLoggedIn: false, } export function UserReducer(state = INITIAL_STATE, action) { switch (action.type) { case types.LOGIN: let isLoggedIn = action.payload.status === 200 ? true : false; return { ...state, isLoggedIn: isLoggedIn, }; case types.LOGIN_SUCCESS: let isLoggedIn1 = action.payload.status === 200 ? true : false; return { ...state, CurrentUser: action.payload.data, isLoggedIn: isLoggedIn1, isLoggedOut:false }; default: return state; } }
Login.js
componentDidUpdate(prevProps) { const prev = prevProps && prevProps.UserReducer; const cur = this.props && this.props.UserReducer; if (prev.isLoggedIn !== cur.isLoggedIn && cur.isLoggedIn==true) { History.push(`/dashboard`) } }
14. When you log in to the application, where do you store the credentials? How do you access it?
Some notes on localStorage.
- localStorage is the browser`s database. The data is stored inside your browser in your computer`s memory. localStorage is specific to an origin. In other words, the localStorage for one website cannot be accessed by another. Initial setup
- Let`s get started. I`ve deployed a simple express server to Heroku for use in testing this application.
- Create a new React application and head into the <App /> component. Install axios using npm install axios and import it inside <App /> Next, create a simple login form that accepts a username and password. Next, let`s complete the function.
This function will work in the following steps:
Send the login details to the server.
If the request is successful (async-await), store the user information in localStorage and set the State of the User.
localStorage.setItem(`user`, response.data); useEffect(() => { const loggedInUser = localStorage.getItem("user"); if (loggedInUser) { const foundUser = JSON.parse(loggedInUser); setUser(foundUser); } }, []); localStorage.clear();
15. What’s the difference between an Element and a Component in React?
React Element - It is a simple object that describes a DOM node and its attributes or properties you can say. It is an immutable description object and you can not apply any methods to it.
eg -
<button class="blue"></button>
React Component - It is a function or class that accepts an input and returns a React element. It has to keep references to its DOM nodes and to the instances of the child components.
const SignIn = () => ( <div> <p>Sign In</p> <button>Continue</button> <button color=`blue`>Cancel</button> </div> );
16. What are refs in React? When to use them?
Refs are a function provided by React to access the DOM element and the React element that you might have created on your own. They are used in cases where we want to change the value of a child component, without making use of props and all. They also provide us with good functionality as we can use callbacks with them.
When to Use Refs
There are a few good use cases for refs:
- Managing focus, text selection, or media playback.
- Triggering imperative animations.
- Integrating with third-party DOM libraries.
// using refs
class App extends React.Component { constructor() { super(); this.state = { sayings: "" }; } update(e) { this.setState({ sayings: this.refs.anything.value }); } render() { return ( <div> Mukul Says{" "} <input type="text" ref="anything" onChange={this.update.bind(this)} /> <br /> <em>{this.state.sayings}</em> </div> ); } } ReactDOM.render(<App />, document.getElementById(`root`));
When to use refs
- Helpful when using third-party libraries.
- Helpful in animations.
When not to use refs
- Should not be used with functional components because they don’t have instances.
- Not to be used on things that can be done declaratively.