React Native Navigation Refresh List Screen on back - reactjs

React Native Navigation Refresh List Screen on back:
this.props.navigation.navigate('Order List', {
order_id: this.state.order_id,
order_status: this.state.od_status,
})

What you want to achive isn't clear, but if want to modify your list of data when going back to your previous screen you could simply use useEffect and modify your list in there.
Note: Your list has to be stored in a local state otherwise the screen wouldn't re-render when updating the list and youl would see no changes on your screen.

better description of the problem would be helpful, but this is general solution for class based components:
componentDidMount() {
this._unsubscribe = this.props.navigation.addListener('focus', () => {
this.loadDataFunction();
}
}
componentWillUnmount() {
this._unsubscribe();
}

Related

How to pop to the previous screen with params?

I'm on screen A which has current state of {key:'value'} , I navigated to screen B
now I'm trying to pop from screen B to screen A again , but I don't want to lose the current state in screen A {key:'value'}
some solution is to save data in the AsynStorage , and retrive it when coming back to screen A , but that's not a good practice
.pop() do it , but what if I need to go back with additional params ?
Navigation.pop(this.props.componentId , {
passProps: {
data : 'current',
more : 'just-example'
}});
the above code , did not work
any suggestions ?
I don't use any state management tool like Redux/Mobx ..
I found a good solution is to send a callback function with the params
in screen A
getback(success)
{
alert(success);
}
Navigation.push(this.props.componentId , { component : {
name : "Payment",
passProps: {
subscription : current,
getback: this.getback
},
}});
then in screen B , when you pop to screen A fire the getback function
Navigation.pop(this.props.componentId);
this.props.getback(true);
this worked well with me
I have been working on this and I achieved with react-navigation.
Basically, your component A will send to component B the navigation state of component A. So, For B point of view it will be the prevState before stacking B component.
So when component B navigates "back" to component A using the previous navigation state it was like your navigation state never changed and now you could use the second parameter of navigate to send params back to component A.
This simple example illustrate this practice and I think it is totally valid and no AsyncStorage usage.
// In Component A use a custom prevState when goes to Component B
const { navigation } = this.props;
navigation.navigate('ComponentB', { prevState: navigation.state });
// In Component B use this custom goBack to "pop" to last screen
function goBack(data) {
const { navigation } = this.props;
const { routeName, key } = navigation.getParam('prevState');
navigation.navigate({ routeName, key, params: data });
}
// And finally in Component A again you could get data like this
function getDataFromComponentB() {
const { navigation } = this.props;
// It is null if no parameters are specified!
return navigation.state.params;
}
If the reason why you wanted navigation.pop is the animation, I have news for you: just use navigation.navigate!
When using the card presentation (for example), doing, from screen B, navigation.navigate(screenA_Id, options), works like navigation.pop
As Terrance suggested. you can use a callback in the props and fire it before pop back to the previous page
answer source: React Native Pass properties on navigator pop
I was working on similar thing which I wan't to popToTop and pass some params when I came back to top of the stack.
here how I did it in react navigation 5 :-
props.navigation.reset({ // I did reset my stack using navigation.reset() instead of using popToTop
index: 0,
routes: [
{
name: "Home", //name of screen which you wan't to come back to it
params: { isDialogOpen: true }, // params you wanna pass to the screen
},
],
});

mxKeyHandler not working when React component is remounted

I'm using mxGraph in a React Single Page Application and instantiating a new mxKeyHandler in componentDidMount. I also invoke its destroy method in componentWillUnmount. It all works fine the first time you visit the page that has the mxGraph component, but if I navigate away to a different page and come back (without a page refresh), it no longer works.
componentDidMount() {
this.editor = new mxEditor();
this.editor.setGraphContainer(this.mxGraphRef.current);
......
this.keyHandler = new mxKeyHandler(this.editor.graph);
this.keyHandler.bindKey(46, evt => {
this.editor.graph.removeCells();
});
}
componentWillUnmount() {
this.keyHandler.destroy();
this.editor.destroy();
}
Any advice as to what I'm doing wrong?
Ok, the solution was to add the following 2 lines:
this.editor.graph.container.setAttribute('tabindex', '-1');
this.editor.graph.container.focus();
As described here: https://jgraph.github.io/mxgraph/docs/known-issues.html#Focus

Preserve internal state on page refresh in React.js

It must be pretty regular issue.
I'm passing props down to the children and I'm using it there to request to the endpoint. More detailed: I'm clicking on the list item, I'm checking which item was clicked, I'm passing it to the child component and there basing on prop I passed I'd like to request certain data. All works fine and I'm getting what I need, but only for the first time, ie. when refreshing page incoming props are gone and I cannot construct proper URL where as a query I'd like to use the prop value. Is there a way to preserve the prop so when the page will be refresh it will preserve last prop.
Thank you!
(You might want to take a look at: https://github.com/rt2zz/redux-persist, it is one of my favorites)
Just like a normal web application if the user reloads the page you're going to have your code reloaded. The solution is you need to store the critical data somewhere other than the React state if you want it to survive.
Here's a "template" in pseudo code. I just used a "LocalStorage" class that doesn't exist. You could pick whatever method you wanted.
class Persist extends React.Component {
constuctor(props) {
this.state = {
criticalData = null
}
}
componentDidMount() {
//pseudo code
let criticalData = LocalStorage.get('criticalData')
this.setState({
criticalData: criticalData
})
}
_handleCriticalUpdate(update) {
const merge = {
...LocalStorage.get('criticalData')
...update
}
LocalStorage.put('criticalData', merge)
this.setState({
criticalData: merge
})
}
render() {
<div>
...
<button
onClick={e => {
let update = ...my business logic
this._handleCriticalUpdate(update) //instead of set state
}}
>
....
</div>
}
}
By offloading your critical data to a cookie or the local storage you are injecting persistence into the lifecycle of the component. This means when a user refreshes the page you keep your state.
I hope that helps!

React with Redux Update only state

I'm working on integrating Redux in an already finished SPA with ReactJS.
On my HomePage I have a list of the 4 newest collections added which on render, I fetch with axios from my database. These are then saved in Redux Store and displayed on the React UI.
My mapStateToProps look something like this:
const mapStateToProps = (state) => ({
credentials: credentials(state),
collections: collections(state)
});
Where credentials is irrelevant and collections is:
const collections = (state) => {
if (state.collectionsHomeViewReducer.fetching === true) {
return {
fetchingCollections: true
}
}
else if (state.collectionsHomeViewReducer.data) {
const response = state.collectionsHomeViewReducer.data;
return {
collections: response.collections,
fetchedCollections: true,
fetchingCollections: false
}
}
else if (state.collectionsHomeViewReducer.fetched === false) {
return {
fetchedCollections: false,
fetchingCollections: false
}
}
};
What is it I want to do:
Update the store state every time another client, or the current client, adds a new collection. Moreover, I do not wish for the UI to update immediately after I dispatch(action), I want it to update when a user refreshes the page or when he navigates to another view and returns ( I believe what I'm trying to say is when componentDidMount is called ).
What have I achieved so far:
By using socket.io, I
socket.emit("updateCollectionsStore")
socket.on("updateCollectionsStore")
and
socket.broadcast.emit("updateCollectionsStore")
in their respective places in the application. The final call of
socket.on("updateCollectionsStore")
after the broadcast, is in the main file of the page, app.jsx where the store is also located. The function there looks like this:
socket.on("updateCollectionsStore", () => {
store.dispatch(getCollectionsHomeView());
});
The store is updated and everything works fine, as viewed from the Redux Dev Tools.
What I can't seem to figure out is to tell the props not to change due to the fact that mapStateToProps is called every time an action is dispatched.
Why do I need this: The HomePage can deal with a continuous UI update and data fetching but I also have a page ReadAllPage where you can real all collections. The problem is if there will always be the newest post on the top, whenever a new one is added, the current one is pushed downwards. In case somebody had the intent to click the one that was pushed down, now he might have accidentally clicked the one that took its place, which is not wanted.
What else should I do different or further to achieve the result I want?
Thank you.
According to your needs, I would have two properties in the state. First is that is currently visible on the HomeView and the second is that is updated via sockets. Once a user navigates to the HomeView you can just replace the first collection with the second one.

React Router "Link to" does not load new data when called from inside the same component

Background
I am building an app with the following details
react
react-router
redux
it is universal javascript
node js
Problem
When routing with the Link tag from component to component it works perfectly. It calls the data that the component requires and renders the page. But when I click on a Link that uses the same component as the current one all I see is the url change.
Attempts
Things I have tried to get this to work.
Attempt 1
So far I have tried the steps in this question but the solution wont work for me. This was the code I implemented
componentWillReceiveProps(nextProps) {
if (nextProps.article.get('id') !== this.props.article.get('id')) {
console.log('i got trigggerd YESSSSSSSSSSSSSSS');
}
}
But the variable nextProps is always the same as the current props.
Attempt 2
I decided to call the same code I use in componentWillMount but that didn't work either.
componentWillMount() {
let { category, slug } = this.props.params;
this.props.loadArticleState({ category, slug });
}
It just creates an infinite loop when I put this into componentWillReceiveProps.
Conclusion
I belief the problem is clicking the link never calls the data associated with it. Since the data is loaded with
static fetchData({ store, params }) {
let { category, slug } = params;
return store.dispatch(loadArticleState({ category, slug }));
}
Any help is appreciated.
Solution I Used
I created a function to test if the previous data is the same as the changed data.
compareParams(prevProps, props) {
if (!prevProps || typeof prevProps.params !== typeof props.params) {
return false;
}
return Object.is(props.params, prevProps.params);
}
So this tests
are there any previous props?
and then if the props are equal to the previous props?
then return false if there are if this is the case
if not then we see compare props and previous props parameters
In ComponentDidUpdate
In the compoonentDidUpdate we use this function to determine if the data should be updated
componentDidUpdate(prevProps) {
if (this.compareParams(prevProps, this.props)) {
return;
}
this.props[this.constructor.reducerName](this.props.params);
}
Conclusion
This code updates the body of a page that uses the same react component if it receives new data.
maybe you can try use onChange event on Route component, check Route API and then signal to child component that refresh is needed...

Resources