Using localStorage with Next.js before componentDidMount - reactjs

We're building an application where we need to store some data in localStorage before componentDidMount is invoked. Is there a way of doing this? It's to store some settings required for various API calls.

According to the docs, your React component's lifecycle will happen in this order. While you could trigger the save to localStorage in in the constructor, or in getDerivedStateFromProps, it sounds like you might want to wait to make the API calls that are being made in componentDidMount until later. You could set up your chain of logic to only fire the API call once localStorage has been written to successfully?

Related

reactjs : Fetching external data

I am learning how to use Reactjs and I read the following post :
https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data
When componentWillMount is used, it is written that The above code is problematic for both server rendering (where the external data won’t be used) and the upcoming async rendering mode (where the request might be initiated multiple times).
I do not understand :
How the request might be initiated multiple times because
componentWillMount is used only one time.
Why componentDidMount solves this problems. For the server rendering,
the external data won't be used also in the first render call.
According to the React docs, changing your component’s state in componentWillMount will not trigger a re-render. This means that if you make your AJAX call and set the response in your component state, it will not re-render, which means you won’t see your data in the DOM. (Remember that the component was initially created with an initial state which most likely didn’t have the data from your external data/AJAX call response)
You could argue that wouldn’t it be better to do my AJAX call to pull external data before the component mounts for the first time?
It wont be better because you don’t know how much time it will take to do your AJAX call. Your AJAX request could take longer to get the data than the time it takes the component to mount and therefore your data does not show up on your DOM as the component has already rendered and there is no re-rendering happening. Your AJAX request could take longer for any reason - your user is on mobile and has slow internet, some issue with your server is making it slow to return responses, etc...
Best thing to do is make your AJAX call in componentDidMount and make your component handle empty data (probably display a loading spinner) until your AJAX request returns the data, sets it to the component state and triggers a re-render! :)
If you read further down they explain a bit more why componentWillMount is problematic.
The above code is problematic for both server rendering (where the
external data won’t be used) and the upcoming async rendering mode
(where the request might be initiated multiple times).
But these may be rendered moot as react is essentially deprecating that lifecycle function come react 17, and thus currently is renamed to UNSAFE_componentWillMount and not recommended for use, but instead use componentDidMount to make your async data fetches.
Why does componentDidMount fix this?
Because the server is pre-rendering the components/JSX, but you don't want the component to fetch its data until after it is actually mounted and running in a browser.
react component lifecycle docs

What is the best practice cause side effects, such as connecting to a webapi, in reactjs, and why?

I'm learning ReactJS currently and I've seen and read that you should use componentDidMount and componentDidUpdate but I don't Understand why should I use it when the side effect is connected to the view.
For an example, I have a submit button in a sign in page, when should I send the api the sign in data? in componentDidMount? or onSubmitHandler?
You should call your api in onSubmitHandler and call it as per your use case.
As for the the componentDidMount, it is generally used to call those methods which are required when a component is mounted.
You can read about lifecycle methods here
I'm not sure the context where some one told you "you should use componentDidMount", but your submit button should call a function you define like "onSubmitHandler".
componentDidMount and componentDidUpdate are called lifecycle methods and you should read about them before deciding if you should use them, and what you should use them for.
As mentioned in the other answers it completely depends upon the use cases, you can call your API in componentDidMount or in onSubmitHandler.
Some common use cases:
When I want to call an API after my view rendered then I will use ComponentDidMount to simply call the API. I will not wait for any click event from user.
If someone told you "you should use componentDidMount", then they are probably talking about this use case. Why call API in ComponentDidMount
If there is a submit button on my page and I want to call API when someone clicks on that then I will use onClick event. I can't call API in ComponentDidMount in that case
There is an awesome article about the lifecycles React 16 Lifecycle Methods: How and when to use them

React + Redux App: Calling API through a Redux action Vs Calling an API directly

I'm working on a React+Redux application. I'm calling APIs through Redux actions and storing the response data in the Redux state. But there is a case, Where I don't have to store the API response data in the Redux store.
So the question is, Is there any valid reason to call the APIs through
Redux actions or Should I call the APIs directly since I'm not storing
the response data in Redux store?
It depends on what kind of call you're trying to make, and who's concern it is.
Here are a few cases:
Is this a one-way call to track something?. You can fire an action that gets picked up in a middleware. this is a good case for sending analytics.
This doesn't have to be stored in Redux's store.
Is this a call where some other part of your application will need this data?, then this is a good use case for making an update in the Redux Store so other components when read this and use props to decide what to render etc.
Is this a call where it only concerns one component or isolated part?. You can make this call inside the component in componentDidMount since this doesn't concern anyone else
Alternatively take a look at Sagas, they observe all actions that get dispatched and decide what to do with them in a clean way.
The accepted answer quite well explains the scenario where from API call can be initiated. For better user experience, we always show some spinner or busy sign to inform the user that a request is being made and it has not finished yet. It may happen that API response is not mutating the state, but to let the user know some task is going in the background, we usually update store (for global access) or state (for component level access) with value like isFetching or anything meaningful.
So, it depends on the developer, whether he/she want to show some busy sign or silently perform the API request. Moreover, if they want to show busy sign then, they should decide which part of the application should be aware of the API call. If it is restricted to the component level only, then no need to make the call in actions, otherwise, for global level, yes it should be inside action.
For the sake of uniformity, you should always follow the redux way, even though all the responses are not stored in Redux. It is also a question if you are not using the response from an API call why are you making the call. This argument is counter-intuitive. If you are using the response in some way better do it the Redux way. It is advised to always store the response to a call to Redux and use it, I am sure you are making API calls to do some action on UI.

Appropriate place to dispatch action for fetching server data

I'm new to React and I'm trying to figure out the best way to request information from the server based on the URL. I'm using Redux and React Router v4.
Let's say I have a route /foo/:id, and a component Foo that will render something based on id. However Foo needs some server data related to id to do so. I believe the way to accomplish this would be to use mapDispatchToProps to create a function that takes id as input, does some async work, dispatches an action, and ultimately updates the redux state.
My question is: where is the most appropriate place to invoke the dispatch? In this scenario, there's no form submission or button click to kick things off. Originally I was thinking of including a check for the id data in render() and fetching if it was not populated, but this felt wrong due to the side effects.
You can do it in componentDidMount of the Foo component, similar to this example from the Redux GitHub project.
Your intuition is right that render is not a good place to do so. Most people do it in the componentDidMount lifecycle method of the component.
On a relevant note, you will also want to do fetching also in the componentWillReceiveProps method like what they did here. Reason being if your user navigated from foo/1/ to foo/2/, the component is already on the screen and will not be mounted again, hence componentDidMount will not be called again. The fetching for the second user will be done in the componentWillReceiveProps method.
i think the best way to do the dispatch inside the componentWillReceiveProps() which would help you fetch some data before the component renders
It seems your use case is well-captured by the react-refetch package which you can find here. It provides a higher-order component that allows you to specify dependencies at specific API endpoints and then resolves them when a new instance of your component is created.
Importantly it injects the data into your components props using a synchronous abstraction of a promise called a PromiseState. This will allow you to conditionally render your component depending on whether the data is say pending, fulfilled, rejected, etc.
This is not attached in any way to Redux, it skips that layer entirely, so do keep it in mind that the response is directly injected into the component and does not go through your redux store's state.

Setting defaul state in a reactivejs/redux app

In my current ReactJS component, I have to call a REST API and get the JSON. It is done in componentWillMount.
I have introduced Redux in my app. Where should I make the call now to get the JSON and set as the default state? Is it in Redux or my React app?
Any example appreciated.
You'll usually want to dispatch an action from componentDidMount (or Will depending on your lifecycle constraints). That action will kick off the XHR and usually return either a thunk (redux-thunk) or a promise (redux-promise-middleware). If a thunk, it will be set up to dispatch another action with the results, or with a promise it does that for you, then reduce that state in as per normal and bind it to the component.
A common practice is to have a configureStore.js file that exports a configureStore() function that handles the store setup (initial state, middleware, and enhancers) and returns your store. See the "real-world" example in the redux repo for an example of this.
In your case, a simple approach would be to request the data from your REST API when your app starts up, and then when you receive the response, call configureStore(initialState) (where initialState is the data you fetched) and then proceed with the rest of the app setup and initial rendering. This approach will add a little time to your app startup though, because its initialization will be paused while it's waiting for that API response.
Another option would be to just create your store normally (without the prerequisite API fetch), and then make the actual initial state request from your API after your store has been created. When that API response is received, you could dispatch an INITIAL_STATE action, and have reducers ready to handle that. In this approach, you'd probably want some sort of loading indicator in place during this initial fetch, since your app will have rendered or at least started to render during the API request.
If you're doing server rendering, you can just fetch the initial state data from the server side, and attach it to the window object of the index.html that you're rendering. See the "universal" example in the redux repo for an example of this. That'll allow you to simply grab your initial state from the window object when you create your store.

Resources