react-native-router-flux Calling Actions from function - reactjs

This is my currently working login page. Everything works fine
import React, { Component } from 'react';
import {AlertIOS , StyleSheet , View , Text} from 'react-native';
import Button from 'react-native-button';
import {Actions } from 'react-native-router-flux';
class Login extends Component {
render() {
return (
<View>
<Text>Hello world this is login page</Text>
<Button onPress={Actions.login2}>Click </Button>
</View>
);
}
}
export default Login;
However, I want to call function first for check the username and password.If it's correct I want to go to next screen. How can i achieve this. Like this code below. My real problem is I couldn't figure out calling Actions.ROUTE_NAME method outside of the render method.
//This is not working
import React, { Component } from 'react';
import {AlertIOS , StyleSheet , View , Text} from 'react-native';
import Button from 'react-native-button';
import {Actions } from 'react-native-router-flux';
class Login extends Component {
controlMethod(){
if(true){Actions.login2}
}
render() {
return (
<View>
<Text>Hello world this is login page</Text>
<Button onPress={this.controlMethod}>Click </Button>
</View>
);
}
}
export default Login;

maybe you can try this one :
controlMethod(){
if(true){ Actions.login2() }
}
let's try using ()
hope it can solve you're problem :)

Rizal is right, in your second example, you passed in controlMethod function to the onPress prop, when you click on <Button> component, the controlMethod will get executed, but in your second example the controlMethod will not actually execute the Actions.login2 function but instead it will return the function expression, so to make it work, you want to actually invoke the Actions.login2 which is why you need another pair of parenthesis after the Actions.login2 just like Rizal's example shows.
Also, make sure you bind your controlMethod in your constructor or you can make it a static method instead.

Related

Navigation inside class component not working

While using class component I cannot use navigation its telling invalid hooks . How can I use navigation inside class component?
this is what i am trying to acheive , navigation option inside class component. actually i a m newbie .Can anyone help me?
import React, { Component } from 'react';
import { Text ,View ,TouchableOpacity } from 'react-native';
import { useNavigation } from '#react-navigation/native';
class Mpin extends Component {
const navigation= useNavigation();
render() {
return (
<Text>....</Text>
<TouchableOpacity onPress={()=>navigation.navigate('LoginPage')}>
<Text>SetMPIN</Text>
</TouchableOpacity>
);
}
}
export default Mpin;
You cannot use hooks inside class component. Inside class component you can directly access navigation object from props.
this.props.navigation.navigate('LoginPage')
Actually I can understand what you are trying to say. I came through this same kind of mistakes when I first started.
Use the below functional component inside of your class component like shown . By doing so you can access navigation inside class component.
import React, { Component } from 'react';
import { Text ,View ,TouchableOpacity } from 'react-native';
import { useNavigation } from '#react-navigation/native';
function ForgotMpin() {
const navigation = useNavigation();
return (
<View>
<TouchableOpacity
style={...}
onPress={() => navigation.navigate("ForgotPin")}
>
<Text>... </Text>
</TouchableOpacity>
</View>
);
}
class Mpin extends Component {
render() {
return (
<Text>....</Text>
<ForgotMpin screenName="forgotMpin" />
);
}
}
export default Mpin;
you can use vanilla js in those cases, the following code helps you redirect or navigate to other paths:
window.locate.replace('/pathname')
if you want to use Navigate or useNavigate you will have to convert to function component and not a class component

How to make an API request In React on button click

I'm trying to build a random quote generator that loads A quote on componentDidMount with an axios api request , then loads new quotes on button click.
This is for A freecodecamp project. I have tried making the call again on button click, then adding the new response to state, but it will not work at all.
import React, { Component } from 'react'
import Button from './Button';
import axios from 'axios'
class QuoteBox extends Component{
constructor(props){
super(props)
this.state = {
quotes: []
}
}
componentDidMount(){
axios.get('http://quotesondesign.com/wp-json/posts?
filter[orderby]=rand&filter[posts_per_page]=1')
.then(res=> this.setState({quotes: res.data[0]}))
}
getNext = (ev) =>{
ev.preventDefault()
axios.get('http://quotesondesign.com/wp-json/posts?
filter[orderby]=rand&filter[posts_per_page]=2')
.then(res=> this.setState({quotes:[...this.state,res.data[0]]}))
}
render(){
const {content,title} = this.state.quotes
const filteredContent = String(content).replace(/(<\w>)|(<\/\w>)|
(&#\d{4})/gm, "").replace(/(;)/g,"'")
console.log(content)
return(
<React.Fragment>
<h2>A little inspiration for the day</h2>
<div className='outerQuoteBox'>
<div className='innerQuoteBox'>
<p>{filteredContent}</p><br/><br/>{title}
</div>
<Button getNext={this.getNext} />
</div>
</React.Fragment>)
}
}
export default QuoteBox
And this is my button component
import React, { Component } from 'react'
export class Button extends Component {
render() {
return (
<React.Fragment>
<button onClick={this.props.getNext} className='nextBtn'
type='button'>Next</button>
</React.Fragment>
)
}
}
export default Button
When I click the button, it seems like the request isn't going through at all. If i check State in the dev tools, only the first quote from componentDidMount is in the array. I don't understand where my mistake is.
Edit: I had used the wrong prop reference, so it wasn't making the call. I fixed this and it does make the call now, and it brings in one new quote, but that's it. And it doesn't add the new one to state, it just replaces it with the one new one. and that's all it will do. The api instructions say the end point i'm using should return a new random quote, but it does not.
It looks like you're referencing the wrong prop on the button.
Change getQuote to getNext and it should work...
import React, { Component } from 'react'
export class Button extends Component {
render() {
return (
<React.Fragment>
<button onClick={this.props.getNext} className='nextBtn'
type='button'>Next</button>
</React.Fragment>
)
}
}
export default Button

Proper way of defining/initializing state in reactjs or react-native

So far I understand there are two ways to define state in react class.
The first as many people use them, is as follows:
import React, { Component } from "react";
import { View, Text } from "react-native";
export default class Test extends Component {
constructor (props) {
super(props)
this.state = {
text: 'hello'
}
}
render() {
return (
<View>
<Text>{this.state.text}</Text>
</View>
);
}
}
The second one is as follows:
import React, { Component } from "react";
import { View, Text } from "react-native";
export default class Test extends Component {
state = {
text: "hello"
}
render() {
return (
<View>
<Text>{this.state.text}</Text>
</View>
);
}
}
The difference is at using constructor or not. What is the effect and is there any difference at all between the two? If there is, which one should I use?
Thank you!
Both methods are correct. Make sure you have support for class properties enabled in the babelrc. If you are using CRA both will work. Constructor one is better on the eyes if you want to seed the initial state from props.
Both methods are fine. Second one is the short-hand method

Passing React Navigation to Child of Child Component

I'm dynamically building my "screen" with the use of child "row" and "button" components. I'm only using this method because I can't find a flex-flow property available for react-native.
So basically I'm mapping through an array of arrays to build each row, and within the row, mapping through each array to build each button. Because the onPress needs to be set in the button, I'm passing the URL for each
onPress{() => this.props.navigation.navigate({navigationURL})
as a prop, first to the row, and then to the button. The problem is I keep getting the error 'Cannot read property 'navigation' of undefined. I'm sure this is because only the actual "screens" within the navigator have access to the navigation props. I've also tried passing
navigation={this.props.navigation}
but had no success. I've looked through all of the documentation and can't seem to find anything helpful. Anyone else encountered a similar situation?
If you want to access the navigation object from a component which is not part of navigator, then wrap that component in withNavigation HOC. Within the wrapped component you can access navigation using this.props.navigation. Take a look at the official document
Sample
import { withNavigation } from 'react-navigation';
...
class CustomButton extends React.Component {
render() {
return <Button title="Back" onPress={() => {
this.props.navigation.goBack() }} />;
}
}
export default withNavigation(CustomButton);
Hope this will help!
Ahhh, silly mistake. I wasn't setting up Props in the constructor. Thank you Prasun Pal for the help! Here's my code if someone else has an issue.
import React, { Component } from 'react'
import { Image, Text, TouchableOpacity, View } from 'react-native'
import { withNavigation } from 'react-navigation'
class ButtonName extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<TouchableOpacity
onPress={() => this.props.navigation.navigate('PageName')}
>
</TouchableOpacity>
)
}
}
export default withNavigation(ButtonName);

Cannot get value from Global State(Redux)

I am having trouble creating this shared component in my project.
This is simplified version of its code:
import React from 'react';
import { View } from 'react-native';
import { connect } from 'react-redux';
function mapStateToProps(state) {
return {
platform: state.device.get('platform') //defines if iOS or Android
};
}
export function SharedView({ theme, ...props }) {
return <View {...props}>{theme}</View>;
}
export default SharedView(
connect(mapStateToProps, null)
);
As I try to add console.log or alert inside of my mapStateToProps I get nothing and it seems I can not see it from my SharedView. I know I could rewrite it to class SharedView extends Component { ..., but for certain reasons I need to keep the format.
Any ideas how to get this global state value?
connect is a higher order function - your component is supposed to be wrapped in it not the other way around.
export default connect(mapStateToProps)(SharedView);

Resources