Push state without retriggering component load - reactjs

Lets say I have only one component which fetches some data on being mounted.
I want to be able to change the url (pushState) once the component fetches that data however I dont want to change anything on the page or re-render the component.
Let's say I have a route '/' and it loads a which fetches searched contents on load. Once the data is fetched, I want to be able to update the url to say /searchterm
I am looking to do something similar to
window.history.pushState(null, null, '/searchterm') where the url is updated but nothing on the page changes.
Tried using with state and using this.props.history.push

You could store the route in your state, and then memoize the component with a function that returns true if the route changes, which will prevent an update. If you're still using class components, you can implement similar functionality using shouldComponentUpdate

Related

Re-render React component and display new data when changing data in MongoDB

My React app is using a modal to create, update, and delete data fetched from mongodb.
This is my component structure:
index.js
making the fetch call to retrieve the data
passing the data as a prop to the admin component (admin component is a route)
admin component
displaying the contents of the data on the page into a grid
open modal component
modal component
create/update/delete data with a form and make a fetch call
I want the admin component to update and show the created/updated/deleted data
immediately after submitting the change in the modal.
I know normally you would have the displayed data as state and then alter that to update the
component and show the new data. In my case that data is getting passed in as a prop to the admin component
from index.js which is fetching the data. I thought another potential way to update the component would be to
create an isUpdated state hook and pass into the modal and toggle its value but that didnt seem to work.
You can try to add real-time updates to your component, so any changes to the data will be reflected without the need of forcing your components to re-render.
You can use streams to get your updates in your database. There is a page with a good tutorial:
https://pusher.com/tutorials/mongodb-change-streams/
This had a fairly simple solution. I was able to solve this by setting the data passed in as props to the admin component in a state hook then pass in the variable and setter function to the modal. In the modal, build a new object with the data collected from the form and use the setter function to push the new data object into the array of the hook and I got the result I wanted. Thanks to the other answerers as well.

Reactjs save current state of component

I have Component A and Component B. In component A, users can apply filters to a list of elements and they navigate between the two components using a side bar. Whenever users click to go to B, and back to A, the filters are set back to the initial state. What is the best way to save the state of component A so that when they come back to it, they see all of the filters they originally applied.
I Suggest you to use LocalStorage , pass in the filter so that it won't be reset. Upon mounting the component , you should always check first if does the localstorage have a value or not.
you can set it via :
localStorage.setItem('variableName', value);
and get it via :
localStorage.getItem('variableName');
It sounds like A is being created/destroyed every time you switch views, so it loses any state that it was storing.
Move the state up to a parent component of both A and B, and pass it down to A via props. The parent component won't be destroyed, so the state will persist.
Thinking in React may help clarify this.
In my knowledge; State in react is not cleared until it is programmed to do so, the page is refreshed or going to another page. Maybe it'll be more clear if you provide your code. One thing which I used to keep previous State is following:
this.setState((previousState) => ({ stateName: previousState.stateName.concat(newValue) }))
I think the parent state of A and B won't change unless you refresh the page.
Another way, you can use AsynStorage or store that data on the Server to retrieve it later when coming back to component A even you refresh the page.

When (where) to read React router params for data retrieval into props?

I have React route:
<Route path='/contract/:id' component={ContractForm}/>
and I would like to read the value of this id param in my ContractForm component for retrieving data from database (of course using REST API and redux-saga) according to the received id value.
I am following React Router Pass Param to Component and it provides solution:
<Route exact path="/details/:id" render={(props)=>{
<DetailsPage id={props.match.params.id}/>
}} />
But I need to process id value some time before rendering. Where (from what event) should I read id value? I am thinking about several events but none of them is satisfying:
I can not read id in ContractForm constructor() or componentDidMount(), because those events are fired only once, if I am navigating from the current contract entity directly to the next contract entity then my ContractForm is not recreated of remounted, so events don't happen
I can not read id in ContractForm componentWillUpdate(nextProps, nextState), because it is not fired during mounting and creation of the component.
I can make special method processParams for reading this.props.match.params and retrieving data from the database.
render() {
const {contractId, description} = this.state;
this.processParams();
return (
<div>...</div>)}
But this method (which is called upon rendering) will update the global params or local params and this will cause the another call of render, so - I should make special logic in processParams to prevent the second round of rendering. I am quite uneasy to make such logic.
So - where (when) to read parameters passed by router?
Tutorials are quite basic and does not go into details.
I am specifically interested into loading REST API data into props. I am aware (thanks to answers) about getDerivedStateFromProps https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops which is exactly the event for loading REST API data into component's state, but I seek similar mechanism (event etc.) for loading REST API data into global store props. Maybe component can not do such loading? maybe application should listen to some navigation event and upon navigation event load data into store props and then application can simply render those global data with the component view.
Maybe it is bad design to load dynamically REST API data into props during runtime? E.g. all the CRUD tutorials:
http://www.thegreatcodeadventure.com/building-a-simple-crud-app-with-react-redux-part-1/
https://medium.com/#rajaraodv/a-guide-for-building-a-react-redux-crud-app-7fe0b8943d0f
https://github.com/maprihoda/react-redux-crud
are loading data into props during initialization of the main component of the application. My intention was that I can load list of conracts initially and then user can select (navigate to) some specific contract and my application will load this contract (extensive graph) into props upon opening of the contract form and reload different contract into props upon navigation to different contract.
You need to implement the componentWillReceiveProps function in your DetailsPage class component. Since the same component is re-rendered with updated params and not re-mounted when you change the route params, this is because params are passed as props to the component and on props change, React components re-render and not re-mounted. you may use this as reference
https://reactjs.org/docs/state-and-lifecycle.html
https://hackernoon.com/reactjs-component-lifecycle-methods-a-deep-dive-38275d9d13c0
You may get the params by using props.params.id
You can read it like
this.props.match && this.props.match.params.id
you can use this.props.match where-ever u needed.
Only make sure you are calling super in constructor with props.
constructor(props){
super(props)
}
With redirection,component is re-mounted.So,lifecycle phase also.

Permanent States in React - React-Router

I have a problem: I have a NavBar that loads an AJAX which retrieves a name and another data. Well, the problem is that this data stores them in states of the declared component itself as NavBar.jsx and when I use routes (react-router) the component is mounted and dismantled losing its states, therefore, every time that change of route has That re-make the AJAX call. This same problem I have for a button 'Enter', which has status 1 and when someone is logged in takes 0 status, but every time I change the route returns to state 1 (as if it were not logged, although it is actually logged). My question is: How can I create states that are maintained despite changing routes? (I know this is not possible, with states I am referring to variables, or anything I can declare that does not change value every time you reassemble the components, in this case NavBar, when changing paths. Thank you.
This can be solved in several ways.
save the returned data in localStorage, check in localStorage before doing the ajax call, is the data exists, just use it instead.
Use redux - this moves the state to the app level instead of the component, unmounting the component will not delete the state.
do not re-render the navbar on each navigation(if it's possible in your app).
See the tutorial for nested routes for react-router ;
https://github.com/reactjs/react-router-tutorial/tree/master/lessons/04-nested-routes
this option means that route changes will only re-render the "internal page" and not constant things like the navbar, submenu, footer etc.

Resetting a component when leaving a page

I have a page in my react/redux app that has a search field and I can make an ajax request based on input and display the result on the screen. The problem is that whenever I leave the page and return back it preserves the data I fetched. What is a conventional way of resetting a component whenever you leave the page? I should probably do something with componentWillUnmount function, but things don't quite work.
You store the state in a redux store. Thus the behavior - the data is still there in the store when you navigate between pages. It needs to be removed upon navigating away from page. This could be done by dispatching a reset action from the componentWillUnmount lifecycle method of the page component.
Do you need to be storing the fetched data in your redux store? If you are looking for the data to be loaded every time you go to the page and reset whenever you leave, just storing the data in component state would probably be a better fit, since it gives you that behavior by default.

Resources