If I try to call the fetchToken()
function it just says that it is not a function. If I put it outside of the render function this.props
is undefined
and i'm not able to call it.
class LoginPage extends Component {
componentDidMount() {
Linking.addEventListener('url', this.handleOpenURL);
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
handleOpenURL(event) {
let code = event.slice(22,86);
console.log(code);
this.fetchToken(code)
}
render() {
function fetchToken(code) {
this.props.actions.fetchToken(code)
}
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<TouchableHighlight style={{backgroundColor: '#9b59b6', height: 70, padding: 20}} onPress={this.openAuth.bind(this)}>
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text style={{color: 'white', fontSize: 16}}>Authenticate with Dribbble</Text>
</View>
</TouchableHighlight>
</View>
)
}
}
In this article, we will learn how to call a function to render in ReactJS. React is having 2 types of components, i.e, Class based and Functional Components, but render method is only in Class based components. So we will make a class based component and call a function in that.
If we just want to run the useEffect function after the initial render, as a second argument, we can give it an empty array. If we pass a second argument (array), React will run the callback after the first render and every time one of the elements in the array is changed.
To call a function inside another function, define the inner function inside the outer function and invoke it.
That said, it's perfectly fine to declare functions inside a render method or more commonly these days a functional component. There are hooks like useCallback that can help with performance but 99% of the time it's not an issue.
You have to bind the instance this
to the function. It is recommend to do this in the constructor.
class LoginPage extends Component {
constructor(props) {
super(props);
this.handleOpenURL = this.handleOpenURL.bind(this);
}
componentDidMount() {
Linking.addEventListener('url', this.handleOpenURL);
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
handleOpenURL(event) {
let code = event.slice(22,86);
console.log(code);
this.props.actions.fetchToken(code);
}
render() {
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<TouchableHighlight style={{backgroundColor: '#9b59b6', height: 70, padding: 20}} onPress={this.openAuth.bind(this)}>
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text style={{color: 'white', fontSize: 16}}>Authenticate with Dribbble</Text>
</View>
</TouchableHighlight>
</View>
)
}
}
There is an even cleaner solution: use ES6 arrow functions:
handleOpenURL = (event) => {
let code = event.slice(22,86);
console.log(code);
this.props.actions.fetchToken(code);
}
fetchToken = (code) => {
this.props.actions.fetchToken(code)
}
And if you are wondering why you do not need it for componentDidMount or componentWillUnmount, it seems that since they are part of the component lifecycle, they are autobinded, but you can also still write them as arrow functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With