React Native make network call before render - react-native

I have a component that displays Users in a ListView which needs to make a fetch call before it renders.
I navigate to this component using:
this.props.navigator.resetTo({ id: 'ListUsers', getusers: true });
In the ListUsers component I have componentWillReceiveProps so that I can make the fetch call before render.
However the method is never called.
Further from ListUsers I can navigate to the AddUser component.
From here either a new user is added or the user can Cancel.
If new user is added, I navigate back to the ListUsers component using:
this.props.navigator.resetTo({ id: 'ListUsers', getusers: true });
At this point componentWillReceiveProps is called.
if user cancelled then I navigate back to the ListUsers component using:
this.props.navigator.pop();
Can anyone help to see what I am doing wrong?

You perfectly described what the documentation says will happen when using componentWillReceiveProps
From the docs:
componentWillReceiveProps
Invoked when a component is receiving new props. This method is not
called for the initial render.
In your scenario, is there any reason why you can't use componentWillMount to make the fetch call? componentWillMount is called right before the component is rendered, and it is the first point you can call setState.
If the problem is you need to guarantee that render only shows certain data before the fetch is completed, there are some strategies to do that, but the simplest way may be to simply set a flag to false in your state in the constructor (if you are developing using ES6 methodology), and flip it to true after the fetch is complete. An if statement in your render method would round out this strategy.
If you want me to put together a more comprehensive example, I can do so.

Related

How to stop going to next life cycle hook in vueJs?

My vue page contains Created, mounted, updated, destroyed hooks. I need to add a condition for page rendering. In my case, in the created hook I make a variable true or false based on a confirm alert and if it true I would like the vue to execute other lifecycle hooks else route to a different page.
Is it possible with vue to do this, if yes, how?
In your created hook if this value is false and you want to redirect to different page you can use location API.
//...
created: function () {
// your code
window.location.replace("https://google.com"); // this will redirect you to another page
}
//...

Change state from other component (without passing setState function)

I have a quite decent background in android but now I am starting digging into react native and I am really confused with the ways to change the state of a component through hooks and set state function.
To the point, I have my main screen and I have many small components which change visibility. This is done by letting the user change some filter settings within dialogs. So the suggested way to do that is by having a hook in my main screen with a list that holds the values for the visibility of each component. But since I change the visibility of the components from inside the modals, every time I want to show a modal I will have to pass in a different function(for example setComponentEnable or setComponentDisabled) to set the state for each component. So my main screen will be polluted from all these small functions. Also I should not forget to mention that my modals are consisted from many smaller components and I will have to pass as deep as it goes the proper function to match the user action.
So my question is, is there a way to do this thing without polluting my main with all these small functions and make it possible for the main screen to update every time the user change the filters within the modals?
I already read about context but the docs say:
Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.
So I dont think that this should be a great case for context use.
What I am trying to do now is create a hook with a list
const [isibility, setVisibility] = useState([]);
create visibility handler functions
const setVisibilityEnable = () => {
...
}
and pass it into my modal.
<MyModal
visibilityHandler={setVisibilityEnable}/>
Is there a way to manipulate the state without passing all these callbacks to the modals? Or maybe is there anyone that can suggest a better and clean solution to avoid end up having a really huge main screen?
you can include all the settings in one object and pass that object to all the components. Then each component will then modify that object accordingly.
const defaultVisibility = {
childComponentOne: true,
childComponentTwo: true,
};
const [visibilityObject, setVisibilityObject] = useState(defaultVisibility);
pass both the function and the object into your child components:
<ChildComponentOne visibilityObject={visibilityObject} setVisibilityObject={setVisibilityObject} />
Then in your child component, you set the visibility like so:
setVisibilityObject({...visibilityObject, childComponentOne: false});
Why you don't just pass a property to your modal and check if changed in oncomponentdidchange method?
componentDidUpdate(prevProps) {
if (this.props.yourPoperty!== prevProps.yourPoperty) {
//do your visibility stuff
}
}
Alternatively you can do it with redux when you connect your components to the store.

How to call method whenever screen loaded, Like always should call method in react native

I am developing react native project and I am loading some graphs from server response.
It is a Tab based app and this code is written in first tab.
But, In some use cases that data is not loading to that graph properly.
I have written that code in componentDidMount(), But it will call only once. But, My requirement is I have to call whenever view loaded, That time only render method is calling.
I have tried to add addlistener for navigation, But, Due to its it not navigation stack throwing error.
I have found some solution like below.
componentDidMount() {
}
fetchGraphData = () => {
//some code fetching from DB and redux based on conditions
}
render() {
this.fetchGraphData();
return (
);
}
}
But, This is not good practice as per code standards.
I am not receiving props, But, We are using some graphs which are
loading from data. My requirement is I have to call api fetch data
method after screen load every time.
Any suggestions, I have to call that fetchGraphData() once render method or view loaded.
Your problem is that when you move the 'fetchGraphData' function to a screen with the 'fetchGraphData' function, you must execute it. This problem can be solved by something simpler than I thought.
componentDidMount() {
this.fetchGraphData();
}
You can try rendering again when you move to a screen with a function.
this.props.navigation.push('functionMoveScreen') // Rendering the screen again.

React native hooks break hot reloading?

Hot reloading works fine with class components but when it comes to function components with hooks such as useState, hot reloading resets its value.
Hooks rely on the calling order to make sense.
https://reactjs.org/docs/hooks-faq.html
There is an internal list of “memory cells” associated with each component. They’re just JavaScript objects where we can put some data. When you call a Hook like useState(), it reads the current cell (or initializes it during the first render), and then moves the pointer to the next one. This is how multiple useState() calls each get independent local state.
From https://github.com/gaearon/react-hot-loader
Hook support
Hooks would be auto updated on HMR if they should be. There is only one condition for it - a non zero dependencies list.
❄️ useState(initialState); // will never updated (preserve state)
❄️ useEffect(effect); // no need to update, updated on every render
❄️ useEffect(effect, []); // "on mount" hook. "Not changing the past"
🔥 useEffect(effect, [anyDep]); // would be updated
🔥 useEffect(effect, ["hot"]); // the simplest way to make hook reloadable
To disable hooks reloading - set configuration option:
import { setConfig } from 'react-hot-loader';
setConfig({
reloadHooks: false,
});

How to deal with state during a screen transition using react native and react navigation

I am getting an object undefined exception during a transition from one screen to another. I have a pretty good idea what is happening, I am just not sure if there is a clean way of handling it without just checking for undefined everywhere.
Here is my scenario:
Source screen references a user object in a Redux store
Navigation is initiated from the source screen to the destination screen.
The destination screen componentDidMount() is called where I clear the user object from the Redux store.
The source screen render() gets called again and the undefined error occurs because I cleared user from the store.
I am assuming that the source and destination screens have some overlap due to the transition. I have tried adding listeners with no luck. I can only get listener handlers to fire for type = action,
I am probably making this more complicated than it is, but I would like to find out if there is a standard way of dealing with this or if I am going about it in a completely wrong way.
Also, my react-navigation is integrated with Redux as per the instructions on React Navigation's website and the Redux React Navigation sample code.
Here is the basic code.
Screen 1
componentDidMount() {
// This is a Redux action that sets an object called user to null
clearUser();
{
Screen 2
render() {
return (
// Other code here
// user is null here because render gets called after Screen1#componentDidMount() gets called
<Text>{user.firstName + ' ' + user.lastName}</Text>
<TouchableOpacity
onPress={() => navigation.dispatch({ type:'NAV_SCREEN_1' })}
>
// button code here
</TouchableOpacity>
// Other code here
)
}
The type of error is "TypeError: Cannot read property 'firstName' of null"
I understand the error and why I am getting it. The user object has been set to null by my Redux action in componentDidMount() of Screen 1 and then Redux causes render of Screen 2 to get called which is referencing a user object which is null.
My question is, is there a special way to accommodate this behavior without having to check if the user object is null every place I need to use it ? Should I call clearUser() somewhere else ?
For the newest version of react-navigation, you can use either addListener, withNavigationFocus or isFocused to detect transition state of the screens.
Another unofficial way is to catch action type NavigationActions.COMPLETE_TRANSITION, in case of using middleware like redux-saga.
As an alternative, you can simply make your Redux-connected screen handle undefined or null state. I had a similar problem and I ended up rendering a loader instead of the screen content when user state is undefined. When I log out, the screen shows a loader for a fraction of a second, then the app navigates away.