Dispatch action in useEffect's cleanup function - javascript

I have a form component in a Material UI <Tab /> which allows users to update their address info. The information is fetched from the API via redux-thunk and the form fields are filled with data from the server before the update has happened.
The problem is that after the user fills the fields with new data and updates their address, the form fields still show the previous state and don't update until the user reloads the page.
To fix the problem, I have implemented useEffect to dispatch the action of fetching user data whenever the isUpdated state is true (which will happen after the updateUserAddress action is fulfilled). This, of course, introduced another issue which was infinite rendering.
In order to fix the infinite dispatch call, I dispatch an action to clear the update state and set it to false in the useEffect's cleanup function. This has solved the issue and whenever the user updates their address, the UI updates and the new values populate the form fields:
// Refresh user after address update
useEffect(() => {
if (updateState) {
dispatch(getUser(userInfo.user_id));
}
// Clear update state
return () => dispatch(clearUpdateState());
}, [dispatch, updateState, userInfo]);
The only problem is that the cleanup function is called every time the user changes back and forth from the Edit Address tab.
Although this approach has fixed my problem, I was skeptical about it and wanted to know if this is the right way of doing this.

The problem is that after the user fills the fields with new data and updates their address, the form fields still show the previous state and don't update until the user reloads the page.
You can do an optimistic update when the update address action is dispatched and simply write the input data into the state - assuming that the update will probably work. This should fill the inputs with the data the user just entered, so for them nothing will change. The update request itself should return the updated data set, so you can save that in redux. Or if it doesn't, fire a get request right after the update.

Related

Redux do not update React form inputs

I'm building a user control panel and I have issues binding current data to the input fields.
On page load all inputs are empty, as soon as I update the code, after the hot reload, the inputs are populated correctly...
Basically, in order to populate the form I need to fetch for the current authenticated user, then set the profile data:
componentDidMount() {
const {
getCurrentUser,
setProfileData,
setContactsdata,
setFaresData,
authenticated,
} = this.props;
if (authenticated) {
getCurrentUser(() => {
const {
user,
} = this.props;
if (user.profile) setProfileData(user.profile);
if (user.contacts) setContactsdata(user.contacts);
if (user.fares) setFaresData(user.fares);
});
}
}
I can not directly bind user data because the form has several widget where user can create or update only their profile, contacts, fares, etc... So all of those have their own Redux crud methods.
Everything work as expected, I just need to understand why my data is not visible on page refresh... and yes only after a code reloading...
I can confirm the reducers return the correct data.

Losing data on a browser refresh in Vue.js application

Background
In a Vue.js application I am calling Getter VueX function in the mount life cycle method. This works great and retrieves all my customer data when the page loads.
The problem I seem to be facing is when I refresh the web page the mount method does not fire and the data is all removed from state which I have no access to till I navigate away from the page and then come back. At the point I return the mount function fires and I have the customer data back again.
Example
mounted() {
this.getCustomers();
},
async getSelected() {
console.log("Customer ", this.customer.email);
this.currentCustomer = this.customer;
this.updateCustomerData.clientID = this.currentCustomer.client_id;
this.updateCustomerData.email = this.currentCustomer.email;
this.updateCustomerData.password = this.currentCustomer.password;
this.customer = this.customer.email;
await this.RECEIVE_CLIENT_NOTES(this.currentCustomer.client_id);
},
That function above calls a VueX Getter to retrieve data that is used inside of a Material Auto Complete Search component. It fires off when I navigate to the page but does not fire at all when I am on the page and refresh. The refresh clears the state and leaves me without data on page reload.
Question
How should I handle page refreshes in order to maintain my data or recall the Getter from VueX to repopulate my data?

How do I hide a load more button when data coming from api is empty using react and redux

GitHub link : https://github.com/rakeshvora2007/github-search-using-react
I am able to create an action using SerachBar.js and send it to reducer and then displaying using UserGithubHandle.js, also I am sending an initial page for first user using searchBar.js.
After displaying the user I am able to show the loadmore button when clicked increments the page number and gets the next payload from api using function loadMoreUserFollower from ../actions/index.js which then passes the data to reducer which takes the previous data and new data and send it to UserFollower.js. Now the USerFollower.js dispplays the data.
Problem is once the data coming in has ended the loadMore button should not be displayed. How do I do it using react and redux pattern.
I found the solution.
When data is coming from reducer to UserFollower.js check for the size of data coming in and based on that setState of isHidden to true if incoming data is less than expected or else it is false. Load more button is displayed based on state of isHidden

Send Info after browserHistory.goBack

I'm building an App with reactjs and in some point I have a SearchForm, then I click on one of the items and in that view I have a back button.
What I want is to populate the search form with the previous data. I already achieved it with localStorage from javascript. And saving the state on componentWillUnmount, the problem is this data is always loaded even if I don't arrive from the go back.
Is there a way to add a kind of state to the goBack to tell it?
So, the best way here is to not use localStorage, and instead use history state.
When the user updates the form, you can do this (optionally debounce it for better performance):
history.replaceState(this.props.location.pathname, {
formData: JSON.stringify(formData),
});
Then when the component loads, you can access that state like this:
const {location} = this.props;
const routeState = location.state && location.state.formData;
if (routeState) {
this.setState({
data: JSON.parse(routeState),
});
}
If they refresh the page, or go to another page and go back, or go back and then go forward, they'll have that state. If they open it in a new tab, they won't have the state. This is usually the flow you want.

Reactjs - getting data from server and updating

(reactjs newbie here)...
I'm using Reactjs to create a page where I have
a simple search box
user types in a search text
data is fetched from the server and is displayed
Now, the "searchText" and "data" are my states and I'm trying to figure out how to update the "results" only after the data is received from the server.
I have an event where I handle whenever user types something as a search text
handleUserInput: function(searchText) {
this.loadDataFromServer(searchText);
this.setState({
searchText: searchText,
});
},
But with the above function, the following thing happens
Initial data is loaded
User types in something
The result is IMMEDIATELY updated to only show the the result that contains the search text (code below), BUT at the same time a request is made to the server to fetch results where the result contains the search text
this.props.products.forEach(function(product) {
if(product.name.toLowerCase().indexOf(this.props.searchText) > -1) {
row =
rows.push(row)
}
}.bind(this));
After about a second, new data is received from the server and the result is refreshed again.
Obviously what I want to do is
Load initial data
User types search text
Request data from the server
Receive data from the server
Update the results
What is the proper way of achieving this?
Don't think searchText should be a state itself. You could just use data fetched from the server to set the state.
Let's say, data is a state property. you could pass a callback to the loadDataFromServer and loadDataFromServer calls this callback once data is fetched on it's onsuccess.
this.loadDataFromServer(searchText, function(data) {
this.setState({data: data}};
});
This way, the component will rerender and show the results, once the data is updated.
So, it is just the first refresh that you want to stop right?
If it is already refreshing once the results come from the server, it seems that all you need to do is not filter the results on the client in step 3 - then the same virtual DOM will be generated as in the first place, so the result list will only update the actual DOM once the server responds.

Categories

Resources