onWillFocus React Native v6 Replacement? - react-native

I want to clear errorMessage, when we navigate from Sign in to Sign up and vice-versa, for that I tried using onWillFocus but it has been deprecated.
Can anyone suggest me the replacement of onWillFocus?

You can use the original useEffect hook prescribed which gets triggered when a screen is loaded and when a state changes. You can either pass [] parameters so it only runs once or you can use a state to check it.
useEffect(() => {
// do you work here
}, []);

Related

How to make api calls when component is loaded multiple times

I need to fetch products each time a user navigates the products screen of a react native app being built with expo. I found out that the component lifecycle hook : componentDidMount is called just once. This is an issue because if the products are updated on the backend / API, if the componentDidMount is not called again when the user visits the product page again, they won't see latest products which defeats the purpose of the app. How may i approach this ?
Thanks
Use componentDidUpdate() method. This will execute automatically before render() method gets triggered.
Please read this to know about the life cycle of react-native.
Call a function inside componentDidUpdate() like this
componentDidMount()
{
this.loadInitialState();
}
and then do your API call and set state in loadInitialState() function. Hope this will work
Hope it helps .feel free for doubts.
You can add a navigation listener: Subscribe to updates to navigation lifecycle
this.props.navigation.addListener(
'didFocus',
() => {
this.getData()
}
)
use WebSocket for realtime application

Whats wrong with 'react-redux.connect()' parameters?

Moving sample redux app from react to react-native.
If I pass non-empty params to react-redux 'connect' function app will crash with
on snack with message about parameter is not a function
on real device (android) about context is text and should be placed in 'Text' component
Simular code works fine on react.
On react native sample - 'connect' with empty parameters will not crash - props just will be empty
Full sample here: https://snack.expo.io/#aaronright/reduxtests
I made this change to your snack, and it seems to run fine on the ios/android simulators.
const actions = {
changeFirstName: actionChangeFirstName,
changeSecondName: actionChangeSecondName,
};
const mapDispatchToProps = dispatch => ({ actions: bindActionCreators(actions, dispatch) });
const AppComponent = connect(
mapStateToProps,
mapDispatchToProps,
)(App);
I also added onChangeText={(text) => this.props.actions.changeSecondName(text)} to your text inputs, changing Second to First for the first name input, so that they would update state. Everything is working for me on those two simulators.
That being said, what exactly is the issue you are having? Connect requires the first param, mapStateToProps, to function, but does not require the second param, mapDispatchToProps. You can pass lodash._ for the first param if you really dont need it

React Hook setState not set on promise

I'm using the Contentful CMS JS SDK and the code below does not update my React Hook state. It's more of a promises combined with react hooks combined with React render issue - I believe. I understand that the promise sets the hook value when it is resolved at a later time, but by that time my component already rendered with the initial data (empty string), so if this is the case, how can I make my component re-render when the react hook state is set with the correct value from the promise, so that my Button displays it.
Any help appreciated. Thanks
Problem lies within here.
...
import client from 'contentful'
const [name, setName] = useState('')
client.getEntry(data.fields.store.sys.id)
.then(entry => setName(entry.fields.name))
.catch(console.error)
console.log('STORE URL', name) // name is not set
...
<Button title={name} /> // name still not set
....
I just tried your code and it seems to work for me. :)
https://codesandbox.io/embed/react-hooks-demo-e4wgo
I think you should use useEffect though as described in this article.

Running api fetch on entering screen

I am creating an app in React Native (create react native) and I am attempting to fetch data from an API every time a user transitions to a screen.
For navigation, I am using the React Navigation library with a combination of Drawer and Stack Navigators.
Typically, I have seen fetch handled via the ComponentDidMount() lifecycle. However, when navigating to a screen in a stack navigator, the ComponentDidMount() lifecycle doesn't appear to trigger and the fetch doesn't run.
Ex. user is on post index, then navigates to add post screen, submits and is redirected to view screen (for that post), then clicks back to return to index. Returning to index does not trigger ComponentDidMount() and fetch isn't run again, so results are not updated.
Additionally, sometimes I need to access navigation params to alter a fetch request when navigation between screens.
I originally was attempting to determine screen transition (when navigation params were passed) via componentWillReceiveProps() method, however, this seemed a bit unreliable.
I did more reading and it sounds like I should be subscribing to listeners (via react navigation). I am having a hard time finding recent examples.
Current process (example)
On the desired screen I would subscribe to listener(s) in the componentDidMount() method:
async componentDidMount() {
this.subs = [this.props.navigation.addListener('willFocus', payload => this.setup(payload))];
}
Based of an example, it sounds like its good practice to remove all subs when unmounting the screen, so I also add:
componentWillUnmount() {
this.subs.forEach((sub) => {
sub.remove();
});
}
then I add a setup() callback method that calls whatever fetch methods I require:
setup = (payload) => {
this.getExampleDataFromApi();
};
Additionally, sometimes I need to access Navigation params that will be used in API queries.
I am setting these params via methods in other screens like so:
goToProfile = (id) => {
this.props.navigation.navigate('Profile', {
exampleParam: 'some value',
});
};
It seems like I cannot access the navigation prop via the provided getParam() method when within callback method from a navigation listener.
For example, this returns undefined.
setup = (payload) => {
console.log(navigation.getParam('exampleParam', []));
};
Instead I am having to do
componentDidFocus = (payload) => {
console.log(payload.action.params.exampleParam);
};
Question
I wanted to ask if my approach for handling fetch when navigating seems appropriate, and if not, what is a better way to tackle handling API requests when navigating between screens?
Thanks, I really appreciate the help!

componentWillMount is deprecated and will be removed in the next major version 0.54.0 in React Native

I use the react native latest version of 0.54.0 and Whenever run the apps on iOS there is found warning about deprecate the lifecycle methods. and also please update the components.
Warning :
componentWillMount is deprecated and will be removed in the next major version. Use componentDidMount instead. As a temporary workaround, you can rename to UNSAFE_componentWillMount.
Please update the following components: Container, Text, TouchableOpacity, Transitioner, View
I Have also change according to the waring add prefix UNSAFE_ each of the method.
UNSAFE_componentDidMount() {
}
UNSAFE_componentWillMount() {
}
UNSAFE_componentWillUpdate(nextProps, nextState) {
}
UNSAFE_componentWillReceiveProps(nextProps) {
}
Although the warning continue. Please help me.
Currently I have hide the YellowBox waring in my Apps.
import { YellowBox } from 'react-native';
render() {
YellowBox.ignoreWarnings([
'Warning: componentWillMount is deprecated',
'Warning: componentWillReceiveProps is deprecated',
]);
}
You should move all the code from the componentWillMount to the constructor or componentDidMount.
componentWillMount() is invoked just before mounting occurs. It is called before render(), therefore calling setState() synchronously in this method will not trigger an extra rendering. Generally, we recommend using the constructor() instead.
Avoid introducing any side-effects or subscriptions in this method. For those use cases, use componentDidMount() instead.
This is the only lifecycle hook called on server rendering.
componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
This method is a good place to set up any subscriptions. If you do that, don’t forget to unsubscribe in componentWillUnmount().
Calling setState() in this method will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.
From the official docs
componentDidMount isn't deprecated and is definitely still safe to use, so there's no need to add UNSAFE_ to that method. The componentWillSomething methods are the ones that seem to be on their way out. Instead of componentWillMount, use a constructor for the stuff that doesn't produce side-effects, and use componentDidMount for the stuff that does.
You should avoid using componentWillSomething in order to use constructor or componentDidMount
However, You have to be very carefully which one you'll use. A typical scenario is when you want to display a loading (using states) immediately after you open a screen
this.setState({ isLoading: true });
...
this.setState({ isLoading: false});
In this kind of case you have to use componentDidMount in order to set states. This is what React said about constructors
Typically, in React constructors are only used for two purposes:
Initializing local state by assigning an object to this.state.
Binding event handler methods to an instance.
You should not call setState() in the constructor(). Instead, if your component needs to use localstate, assign the initial state to this.state directly in the constructor.
Good coding!