React native router flux; slow to load back to previous component - react-native

I'm using react-native-router-flux in my Card component to to link to my playerPage component.
This is my Card component:
class Card extends Component {
state = {
visible: false,
currentUser: ''
}
componentDidMount() {
if(this.props.player !== undefined){
axios.get(`http://localhost:4000/reports?players=${this.props.player}&startDate=2019-03-20T03:10:43.990Z&sort=date`)
.then(response => {
console.log(response)
this.props.loadCards(response.data)
})
} else if(this.props.team !== undefined) {
axios.get(`http://localhost:4000/reports?team=${this.props.team}&startDate=2019-03-20T03:10:43.990Z&sort=date`)
.then(response => {
console.log(response)
this.props.loadCards(response.data)
})
} else if(this.props.league !== undefined) {
console.log('got here')
axios.get(`http://localhost:4000/reports?league=${this.props.league}&startDate=2019-03-20T03:10:43.990Z&sort=date`)
.then(response => {
console.log(response)
this.props.loadCards(response.data)
})
} else {
axios.get(`http://localhost:4000/reports?league=NBA&league=NFL&league=MLB&startDate=2019-03-20T03:10:43.990Z&sort=date`)
.then(response => {
this.props.loadCards(response.data)
})
Auth.currentAuthenticatedUser()
.then((data) => {
this.props.loadFilters(data.attributes.sub)
this.setState({currentUser: data})
})
}
}
render() {
let cardValues = this.props.search === null ? this.props.card : this.props.search
return (
<View >
{
cardValues != null ?
cardValues.map((v,i) => {
return(
<View key={i}>
<Collapse
>
<CollapseHeader
>
<View>
<Text>
<Icon
name={this.iconName(v.player.team.league.acronym)}
size={12}
color='black'/>{' '}
<Text
onPress={
()=> {
Actions.playerPage({
player: v.player._id
})
}
}
>{v.player.player_name} - </Text>
</Text>
<Text>
<View>
</View>
</View>
<View>
</View>
</CollapseHeader>
</Collapse>
</View>
)
})
: null
}
</View>
)
}
}
export default connect(mapStateToProps, { loadCards, countMore, loadFilters })(Card))
This is my playerPage component:
PlayerPage = (props) => {
return(
<View>
<Header
rounded
>
<View style={{flexDirection: 'row', flexWrap: 'wrap', right: '43%', top: '50%', paddingBottom: 900}}>
<Icon name='chevron-left' size={10} color='#006FFF' />
<NativeText
onPress={() => {Actions.fullApp()}}
style ={{color: '#006FFF', fontSize: 12, fontFamily: 'Montserrat-Regular', top: '900%' }}
>
Back
</NativeText>
</View>
</Header>
<Card
player={props.player}
team={props.team}
league={props.league}
/>
</View>
)
}
export default PlayerPage
When I link to playerPage I render a new version of Card on playerPage.
The data that is shown on playerPage is determined by the API call in the componentDidMount of the Card component.
I initially direct to playerPage with onPress={ ()=> {Actions.playerPage({player: v.player._id})}}
This loads fine.
When I direct a user back to the fullApp component, which has the Card component on it, the data loads, but much more slowly.
This is what it looks like:
https://streamable.com/ugc0b
Any ideas why it loads slowly? That's my issue.

Related

React native WARN Possible Unhandled Promise Rejection (id: 2): Error: [AsyncStorage] Passing null/undefined as value is not supported

In react native cli i was trying to login but not working nd same thing working fine in expo nd this error is showing please let me know what can i do to do this???? i have added the action ,reducer,component page
getting error this //
WARN Possible Unhandled Promise Rejection (id: 2):
Error: [AsyncStorage] Passing null/undefined as value is not supported. If you want to remove value, Use .removeItem method instead.
Passed value: undefined
Passed key: userToken
checkValidInput#http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.easylab&modulesOnly=false&runModule=true:146791:24
http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.easylab&modulesOnly=false&runModule=true:146835:24..........................
my action is like this // actions>index.js page
export const login = (formValues, actions) => {
return async dispatch => {
dispatch(startSubmitting());
const url = `/auth/login`;
var formdata = new FormData();
formdata.append('email', formValues.email);
formdata.append('password', formValues.password);
const response = await api
.post(url, formdata)
.then(res => {
return res;
})
.catch(error => {
actions.setErrors(error.response.data.error);
return error.response;
});
dispatch({
type: 'LOGIN',
payload: response,
});
dispatch(stopSubmitting());
await AsyncStorage.setItem('userToken', response.data.access_token);
};
};
//my component page login.js
import { StatusBar } from "expo-status-bar";
import React, { useState, useEffect } from "react";
import {
Field,
Form,
Formik,
FormikProps,
ErrorMessage,
useFormik,
} from "formik";
import { connect } from "react-redux";
import { login } from "../../../actions";
import { Button } from "react-native-paper";
import ErrorMsg from "./ErrorMsg";
class Login extends React.Component {
submitLogin = (values, actions) => {
this.props.login(values, actions);
};
render() {
const { onChangeText, text, navigation } = this.props;
const { isSubmitting ,isLoading} = this.props.commonData;
const { login, loginLoading, isLoggedIn } = this.props.loginForm;
{
login && this.props.navigation.navigate("Nav1");
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container}
>
{/* {verifyOtp ? <Loader loading={verifyOtp} /> : null} */}
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.inner}>
<View style={{ alignItems: "center" }}>
<Image
source={require("../../../assets/images/diabetes-awareness-month-1440x810.jpg")}
style={{
height: 110,
// top: -20,
resizeMode: "contain",
}}
/>
</View>
<View style={{}}>
<Text onPress={() => this.props.navigation.navigate("Register")}>
New User ? Register
</Text>
</View>
<View style={{}}>
<Text style={{ fontSize: 24, fontWeight: "bold" }}>LOGIN</Text>
</View>
<View style={{}}>
<Formik
initialValues={{
email: "",
password: "",
}}
validate={(values) => {
const error = {};
if (!values.password) {
error.password = (
<Text style={{ color: "red", fontSize: 10 }}>
Password Required
</Text>
);
}
if (!values.email) {
error.email = (
<Text style={{ color: "red", fontSize: 10 }}>
Email Type Required
</Text>
);
}
return error;
}}
onSubmit={(values, actions) => {
this.submitLogin(values, actions);
}}
enableReinitialize={true}
>
{(props: FormikProps<any>) => (
<>
<View style={{ paddingBottom: 10 }}>
<Text>Login To Check Your Account</Text>
</View>
<View>
{/* email */}
<View style={{ marginBottom: 20 }}>
<View style={styles.textInputContainer}>
<MaterialCommunityIcons
style={{ alignSelf: "center", paddingLeft: 10 }}
name="email"
size={28}
/>
<TextInput
style={styles.input}
onChangeText={props.handleChange("email")}
value={props.values.email}
autoFocus={true}
placeholder="Email"
/>
</View>
</View>
<View style={{ marginBottom: 20 }}>
<View style={styles.textInputContainer}>
<MaterialCommunityIcons
style={{ alignSelf: "center", paddingLeft: 10 }}
name="security"
size={28}
/>
<TextInput
style={styles.input}
onChangeText={props.handleChange("password")}
maxLength={10}
secureTextEntry={true}
value={props.values.password}
placeholder="Password"
/>
</View>
</View>
{/* {props.touched.password && props.errors.password && ( */}
<ErrorMsg msg={props.errors.password} />
{/* )} */}
<TouchableHighlight
underlayColor="white"
onPress={props.handleSubmit}
>
<Text color="white" style={styles.buttonStyle}>
{/* {isSubmitting ? (
<ActivityIndicator
size="small"
color="#4DB2F8"
/>
) : ( */}
<Text>LOGIN </Text>
{/* )} */}
</Text>
</TouchableHighlight>
</View>
</>
)}
</Formik>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
);
}
}
const mapStateToProps = (state) => {
return {
loginForm: state.loginData,
commonData: state.commonFunctions,
};
};
export default connect(mapStateToProps, { login })(Login);
and in redux trying to store like this// reducers>index.js page
const loginReducer = (
state = {
otp: false,
mobile: null,
login: false,
loginLoading: true,
verifyOtp: false,
isLoggedIn: false,
},
action
) => {
switch (action.type) {
case "LOGIN": {
if (action.payload.status === 200) {
let newState = { ...state, login: true, isLoggedIn: true };
return newState;
} else {
let newState = { ...state, login: false, isLoggedIn: false };
return newState;
}
}
default:
return state;
}
};
export default combineReducers({
loginData: loginReducer,
});
Your problem is that you are trying to set userToken to null on this line:
await AsyncStorage.setItem('userToken', response.data.access_token);
You need to do a null check before setting the token, since Async Storage does not support setting null values. Try:
if (response && response.data && response.data.access_token) {
await AsyncStorage.setItem('userToken', response.data.access_token);
}

How to call Parent component function inside custom drawer

I am beginner in React Native. I am getting stuck in one issue. I have one Parent component Home.js in which there is Tab navigator on click of tab 3 child components replace based on selected key. In same page, I have custom drawer.Now, I want to change tabs on click of custom drawer's option & same thing when my 1st tab selected 1st option of drawer also set selected. How can i achieve this.
Here is my navigation Drawer :
export default MyDrawerNavigator = DrawerNavigator({
Page1: {
screen: props => <Home {...props} />,
}
},
{
contentComponent: props => (<CustomSideMenu {...props} />),
drawerWidth: (getScreenWidth() * 2.5) / 3,
}
);
Here is my Home class I want to access goToNextTab() inside Custom drawer
export class Home extends React.Component {
static navigationOptions = hidenavigation;
constructor(props) {
super(props);
}
apply_header = (val) => {
this.props.navigation.setParams({ Title: val });
}
goToNextTab = (tabName) => {
this.setState({ activeTab: tabName });
}
openDrawer() {
this.props.navigation.openDrawer();
}
tabs = [{
key: 'Dashboard',
icon: 'speedometer',
label: 'Dashboard',
pressColor: 'rgba(255, 255, 255, 0.16)'
},
{
key: 'Add Diamond',
icon: 'plus-circle-outline',
label: 'Add Diamond',
pressColor: 'rgba(255, 255, 255, 0.16)'
},
{
key: 'Diamond',
icon: 'diamond-stone',
label: 'Diamond',
pressColor: 'rgba(255, 255, 255, 0.16)'
}]
state = {
activeTab: 'Dashboard',
showFooter: true
};
renderIcon = icon => ({ isActive }) => (
<Icon size={24} color={isActive ? COLOR.action_bar : COLOR.tab_deselected_text_color} name={icon} />
)
renderTab = ({ tab, isActive }) => (
<FullTab isActive={isActive} key={tab.key} label={tab.label} labelStyle={isActive ? style.activeText : style.deactiveText} renderIcon={this.renderIcon(tab.icon)} />
)
render() {
const propsForChild = {
goToNextTab: (tabName) => this.goToNextTab(tabName),
openDrawer: () => this.openDrawer()
};
const propsForNav = {
nav: this.props,
openDrawer: () => this.openDrawer()
};
const addDimPropsForChild = {
openDrawer: () => this.openDrawer()
}
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
{
this.state.activeTab === 'Add Diamond' ? <Add_Dimond_Stack screenProps={addDimPropsForChild} /> : this.state.activeTab === 'Diamond' ? <Dimond_List_stack screenProps={propsForNav} /> : <Dashboard_Stack screenProps={propsForChild} />
}
</View>
{
this.state.showFooter ?
<BottomNavigation activeTab={this.state.activeTab} renderTab={this.renderTab} tabs={this.tabs} onTabPress={newTab => { this.setState({ activeTab: newTab.key }); }} />
: null
}
</View>
);
}
componentWillMount() {
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
}
componentWillUnmount() {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
_keyboardDidShow() {
//alert('Keyboard Shown');
this.setState({ showFooter: false })
}
_keyboardDidHide() {
//alert('Keyboard Hidden');
this.setState({ showFooter: true })
}
componentDidMount() {
printLogs('call', 'componentDidMount')
const { setParams } = this.props.navigation;
setParams({ myProps: 'test' });
}
}
Here is my Custom Drawer in which i want to access setSelectedPos() from Home tab click
export default class Custom_Side_Menu extends React.Component {
static navigationOptions = { hidenavigation };
state = {
current_selected: 0
}
setSelectedPos(pos) {
this.setState({ current_selected: pos });
}
closeNavigationPanel(pos) {
if (pos != 3) {
this.props.navigation.closeDrawer();
}
}
redirectToProfile() {
new NavigationRedirection().goToNextScreen('profile', this.props);
}
selectedColor(pos) {
if (this.state.current_selected === pos) {
return COLOR.input_text_color;
} else {
return COLOR.input_hint_color;
}
}
render() {
return (
<ScrollView>
<View style={stylePage.bg}>
{/* */}
<View style={{ flex: 1 }}>
<View style={{ padding: 10, alignContent: 'center', flexDirection: 'row', alignItems: 'center' }}>
<TouchableOpacity onPress={() => { this.closeNavigationPanel() }}>
<Icon name="arrow-left" size={30} color={COLOR.input_text_color} />
</TouchableOpacity>
<Text style={stylePage.menu_title}>Menu</Text>
</View>
<TouchableWithoutFeedback onPress={() => {
this.redirectToProfile();
}}>
<View>
<Image style={stylePage.profileImage} source={{ uri: 'https://uinames.com/api/photos/female/22.jpg' }} />
<Text style={stylePage.name}>Ruth McCoy</Text>
<Text style={stylePage.email}>ruth.mccoy#example.com</Text>
</View>
</TouchableWithoutFeedback>
<View style={stylePage.line_seprator} />
<View style={stylePage.menu_options}>
<Text style={[stylePage.menu_text, { color: this.selectedColor(0) }]} onPress={() => this.setCurrentSelection(0)}>Dashboard</Text>
<Text style={[stylePage.menu_text, { color: this.selectedColor(1) }]} onPress={() => this.setCurrentSelection(1)}>Diamonds List</Text>
<Text style={[stylePage.menu_text, { color: this.selectedColor(2) }]} onPress={() => this.setCurrentSelection(2)}>Add diamonds</Text>
<Text style={[stylePage.menu_text, { color: this.selectedColor(3) }]} onPress={() => this.setCurrentSelection(3)}>Profile</Text>
<Text style={[stylePage.menu_text, { color: this.selectedColor(4) }]} onPress={() => this.setCurrentSelection(4)}>Change Password</Text>
</View>
</View>
<TouchableOpacity style={{ alignSelf: 'baseline' }} onPress={() => clearAllData(this.props)}>
<View style={stylePage.logout_btn}>
<IconAnt name="logout" size={25} color={COLOR.white} />
<Text style={stylePage.logout_title}>Logout</Text>
</View>
</TouchableOpacity>
<RBSheet
closeOnDragDown={true}
closeOnPressMask={false}
ref={ref => { this.RBSheet = ref }}
height={getScreenHeight() / 2} duration={250} customStyles={{
container: { padding: 10, borderTopLeftRadius: 20, borderTopRightRadius: 20 },
}}>
<ChangePassword {...this.props} RBSheet={this.RBSheet} />
</RBSheet>
</View>
</ScrollView>
);
}
setCurrentSelection(pos) {
this.closeNavigationPanel(pos);
this.setSelectedPos(pos);
if (pos === 3) {
this.redirectToProfile();
} else if (pos === 4) {
this.RBSheet.open();
} else {
printLogs('props', this.props.navigation)
}
}
}
There are two problems.
Click on drawer options to change the navigation tab
On tab change set the option as active
using redux as global store
There is an easy way out if you need redux as your global store.
first connect your components with react-redux connect
manage the activeTab state in store instead of component state
then on click of drawer option change the state in redux for your activetab
this way you are able to solve the problem 1
Also make sure you check activetab from store if matched you can update the styling for active option in drawer . So here is solution for problem 2
Using tab navigator from react-navigation
another option is using tabNavigator from react-navigation itself that way you only need to call navigator function for changing tab
and getting the active tab from navigation state
* alternate to redux *
you can use react context apis for managing your parent state if you are not using redux

Using parameter that would fetch data from another api based on a condition react native?

I have two pages Portfolio.js and PortfolioDetails.js. In the Portfolio.js file, I am fetching data from my api and displaying all the portfolios in a list. When I click on portfolio, it should take me to the PortfolioDetails screen, which will display only those stocks from stock api which are in the portfolio.
e.g if I click on Portfolio with id 1, it should filter out stocks from stock api which has portfolio id 1 and display all those stocks on the screen.
So far, I am successful in fetching both the apis and also when I click on one portfolio, it passes the portfolio id parameter to my PortfolioDetails screen. I am stuck where I have to filter the stocks to display based on this passed parameter - id.
Portfolio.js file
export default class Portfolio extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: "Portfolio",
header: null,
};
};
constructor(props) {
super(props);
this.state = {
loading: true,
PortfolioSource: []
};
}
componentDidMount() {
fetch("http://127.0.0.1:8000/portfolios/")
.then(response => response.json())
.then((responseJson) => {
this.setState({
loading: false,
PortfolioSource: responseJson
})
})
.catch(error => console.log(error)) //to catch the errors if any
}
FlatListItemSeparator = () => {
return (
<View style={{
height: .5,
width: "100%",
backgroundColor: "rgba(0,0,0,0.5)",
}}
/>
);
}
renderItem = (data) =>
<TouchableOpacity style={styles.list} onPress={() => this.props.navigation.push('Details', { portid: data.item.id })} >
<Text style={styles.lightText}>{data.item.id}</Text>
<Text style={styles.lightText}>{data.item.portfolio_id}</Text>
<Text style={styles.lightText}>{data.item.name}</Text>
<Text style={styles.lightText}>{data.item.description}</Text>
<Text style={styles.lightText}>{data.item.gains}</Text></TouchableOpacity>
render() {
if (this.state.loading) {
return (
<View style={styles.loader}>
<ActivityIndicator size="large" color="#0c9" />
</View>
)
}
return (
<View style={styles.container}>
<FlatList
data={this.state.PortfolioSource}
ItemSeparatorComponent={this.FlatListItemSeparator}
renderItem={item => this.renderItem(item)}
keyExtractor={item => item.id.toString()}
/>
</View>
)
}
}
PortfolioDetails.js
export default class PortfolioDetails extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: "PortfolioDetails",
header: null,
};
};
constructor(props) {
super(props);
this.state = {
loading: true,
PortfolioDetailsdataSource: [],
};
}
componentDidMount() {
fetch(`http://127.0.0.1:8000/stocks/`)
.then(response => response.json())
.then((responseJson) => {
this.setState({
loading: false,
PortfolioDetailsdataSource: responseJson
})
})
.catch(error => console.log(error)) //to catch the errors if any
}
FlatListItemSeparator = () => {
return (
<View style={{
height: .5,
width: "100%",
backgroundColor: "rgba(0,0,0,0.5)",
}}
/>
);
}
goToPrevScreen = () => {
this.props.navigation.goBack();
}
renderItem = (data) =>
<TouchableOpacity style={styles.list}>
<Text style={styles.lightText}>{data.item.id}</Text>
<Text style={styles.lightText}>{data.item.ticker}</Text>
<Text style={styles.lightText}>{data.item.price}</Text>
<Text style={styles.lightText}>{data.item.market_cap}</Text>
<Text style={styles.lightText}>{data.item.YTD}</Text>
<Text style={styles.lightText}>{data.item.OneYear}</Text>
<Text style={styles.lightText}>{data.item.TwoYear}</Text>
<Text style={styles.lightText}>{data.item.TTM_Sales_Growth}</Text>
<Text style={styles.lightText}>{data.item.PE_Ratio}</Text>
</TouchableOpacity>
render() {
if (this.state.loading) {
return (
<View style={styles.loader}>
<ActivityIndicator size="large" color="#0c9" />
</View>
)
}
return (
<View style={styles.container}>
<FlatList
data={this.state.PortfolioDetailsdataSource}
ItemSeparatorComponent={this.FlatListItemSeparator}
renderItem={item => this.renderItem(item)}
keyExtractor={item => item.id.toString()}
/>
<Text> portid: {this.props.navigation.state.params.portid} </Text>
<Button
onPress={() => this.goToPrevScreen()}
title="go back to Portfolio"
/>
</View>
)
}
}
You can use .find(). For example:
PortfolioDetailsDataSource.find(item => item.id === this.props.navigation.state.params.portId)
Assuming IDs are unique, this will return the desired object, otherwise it will return the first occurrence that passes the condition.

Pass function in react native prop

I currently have a screen that lists items with star ratings on them.
This is created due to the following JSX being returned by a _renderItem function for a FlatList component. :
<TouchableOpacity
delayPressIn={70}
activeOpacity={0.8}
onPress={() => {
navigate("WellbeingBreakdown", {
id: info.item.id,
});
}}
>
<RkCard rkType="horizontal" style={styles.card}>
<Image
rkCardImg
source={info.item.icon}
/>
<View rkCardContent>
<RkText rkType="small">{info.item.title}{' '}<Ionicons name="ios-information-circle-outline" size={18} color="gray"/></RkText>
<View style={{flexDirection: 'row', paddingVertical: 10}}>
<Rating
type='custom'
onFinishRating={this.ratingCompleted}
imageSize={20}
ratingColor={RkTheme.current.colors.primary}
ratingImage={STAR_IMAGE}
style={{paddingVertical: 8}}
startingValue={2} /*I want to change this to be dynamic */
/>
<RkButton
rkType="rounded small"
style={{backgroundColor: RkTheme.current.colors.primary, marginLeft: 15}}
onPress={() => navigate("DynamicActivityAssessor", {
id: info.item.title
})
}
>Assess</RkButton>
</View>
</View>
</RkCard>
</TouchableOpacity>
What i would like to do, is dynamically fetch data (from an API) and pass the user's ratings for each item into the startingValue prop of the Rating component.
The API if called returns an array. So accessing response[0] gives you an object similar to this (values depending on if its an activity or diet rating etc):
{
"ActivityTotalScore": null,
"DietTotalScore": 1,
},
So i thought a function roughly like so would work, but i can't figure out how to pass it to that prop. Note - info.item.id is the title of the rendered item in question. So it is equal to 'Activity' or 'Weight' etc
getScore(info){
fetch(`${server_url}data/Wellbeing?where=type%3D`+info.item.id, {
method: "GET", // or 'PUT' // data can be `string` or {object}!
headers: {
"Content-Type": "application/json"
}
})
.then(res => res.json())
.catch(error => console.error("Error:", error))
.then(response => {
return response[0][info.item.id+'TotalScore'] ;
}
)
}
The simple way is to create a new Component that representents your card. It could be
// In AssessCard.js
import React from 'react';
// Others imports
export default class AssessCard extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
rating: 0,
item: props.item
};
}
componentDidMount() {
this._loadRating();
}
_loadRating() {
fetch(`${server_url}data/Wellbeing?where=type%3D`+info.item.id, {
method: "GET", // or 'PUT' // data can be `string` or {object}!
headers: {
"Content-Type": "application/json"
}
})
.then(res => res.json())
.catch(error => console.error("Error:", error))
.then(response => {
this.setState({ rating: response[0][info.item.id+'TotalScore'] }); // HERE WE'RE SAVING THE RATING
}
)
}
render() {
const { rating, item } = this.state;
return (
<TouchableOpacity
delayPressIn={70}
activeOpacity={0.8}
onPress={() => {
navigate("WellbeingBreakdown", {
id: item.id,
});
}}
>
<RkCard rkType="horizontal" style={styles.card}>
<Image
rkCardImg
source={item.icon}
/>
<View rkCardContent>
<RkText rkType="small">{item.title}{' '}<Ionicons name="ios-information-circle-outline" size={18} color="gray"/></RkText>
<View style={{flexDirection: 'row', paddingVertical: 10}}>
<Rating
type='custom'
onFinishRating={this.ratingCompleted}
imageSize={20}
ratingColor={RkTheme.current.colors.primary}
ratingImage={STAR_IMAGE}
style={{paddingVertical: 8}}
startingValue={rating} // HERE WE USE RATING PROP OF THIS COMPONENT
/>
<RkButton
rkType="rounded small"
style={{backgroundColor: RkTheme.current.colors.primary, marginLeft: 15}}
onPress={() => navigate("DynamicActivityAssessor", {
id: item.title
})
}
>Assess</RkButton>
</View>
</View>
</RkCard>
</TouchableOpacity>
);
}
}
//in file contening your _renderItem function
import AssessCard from './somewhere/AssessCard';
/* CODE */
_renderItem (info) => {
return <AssessCard item={info.item} />
}

Tabbed navigation between screens in react native

I use a StackNavigator based on the react-native-elements example and I want to enable something similar to a link with an ID as a parameter. I want to link to this screen:
const FontsTab = StackNavigator({
Home: {
screen: FontsTabView,
path: '/',
navigationOptions: ({ navigation }) => ({
title: 'Fonts',
headerLeft: (
<Icon
name="menu"
size={30}
type="entypo"
style={{ paddingLeft: 10 }}
onPress={() => navigation.navigate('DrawerOpen')}
/>
),
}),
},
Detail: {
screen: FontsDetailTabView,
path: 'fonts_detail',
navigationOptions: {
title: 'Fonts Detail',
},
},
});
I have this screen where I want the click of the text of an item to open the FontsTabView with the ID as a parameter. I would like to achieve something like the following:
<Text onPress={ (navigation)=> navigation.navigate('FontsTabView ', { id: {item.id} }) } style={styles.listHeader} >{item.title}</Text>
How can it be done?
class Icons extends Component {
constructor() {
super();
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.state = {
selectedIndex: 0,
value: 0.5,
dataSource: ds.cloneWithRows(list1),
isLoading: true
};
this.updateIndex = this.updateIndex.bind(this);
this.renderRow = this.renderRow.bind(this);
}
updateIndex(selectedIndex) {
this.setState({ selectedIndex });
}
renderRow(rowData, sectionID) {
return (
<ListItem
key={sectionID}
onPress={log}
title={rowData.title}
icon={{ name: rowData.icon }}
/>
);
}
_renderList = ({ item, navigation }) => {
return (
<TouchableWithoutFeedback onPress={(event) => this._selectedItem(item.key)}>
<View style={styles.listRowContainer}>
<View style={styles.listinside1Container}>
<Image style={styles.listImage} source={item.icon} />
<View style={styles.listContainer} onPress={(event) => this._selectedItem(item.text)} >
<Text onPress={ (navigation)=> navigation.navigate('DrawerOpen') } style={styles.listHeader} >{item.title}</Text>
<Text style={styles.listValue} >{item.value}</Text>
<Image
style={{width: 50, height: 50}}
source={{uri: item.img}}
/>
</View>
</View>
</View>
</TouchableWithoutFeedback>
);
}
componentDidMount(){
return fetch('https://www.koolbusiness.com/in.json')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.movies,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}
render() {
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator/>
</View>
)
}
const { navigation } = this.props;
const buttons = ['Button1', 'Button2'];
const { selectedIndex } = this.state;
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator/>
</View>
)
}
return (
<ScrollView>
<View style={styles.headerContainer}>
<Icon color="white" name="invert-colors" size={62} />
<Text style={styles.heading}>Trending Ads India</Text>
</View>
<View style={styles.MainContainer}>
</View>
<View style={styles.mainWrapper} >
<FlatList data={this.state.dataSource} renderItem={this._renderList} keyExtractor={(item, index) => index.toString()} />
</View>
</ScrollView>
);
}
}
You were close but not quite there,
Try to render your item like below;
<Text onPress={ ()=> this.props.navigation.navigate('FontsTabView', { id: item.id }) } style={styles.listHeader} >
{item.title}
</Text>
Then in FontsTabView you can read the parameter like below and render your screen accordingly.
this.props.navigation.state.params.id