Why is my custom component not rendering in React Native? - reactjs

I have created a component called OrderGuideSelect and I am trying to render it in another area of our app. The problem is the OrderGuideSelect component is not rendering. When I set up breakpoints I am able to hit inside of the renderOrderGuideOptions function but it never makes it into the OrderGuideSelect.js file. I also tried putting 'export default' in front of the class declaration instead of the connection but it didn't make a difference. Does anyone know how to get the OrderGuideSelect component rendering properly?
Here is where I call the function that renders the OrderGuideSelect component:
<TouchableOpacity onPress={() => this.renderOrderGuideOptions()}>
<MBIcon name="ico-24-filter" size={30} style={styles.filterIcon}/>
</TouchableOpacity>
And here is the rendering function:
renderOrderGuideOptions = () => {
return (
<View>
<OrderGuideSelect />
</View>
)
}
Here is the OrderGuideSelect.js file:
import React, {Component} from 'react';
import {View, FlatList, ActivityIndicator, StyleSheet} from 'react-native';
import {connect} from 'react-redux';
import {fetchOrderGuides} from '../../actions/AppActions';
import {orderGuideSelected} from '../../actions/ProductAction';
import Header from '../../components/Header/Header';
import {createIconSetFromIcoMoon} from 'react-native-vector-icons';
import selection from '../../selection';
import OrderGuideOption from './OrderGuideOption';
const MBIcon = createIconSetFromIcoMoon(selection);
class OrderGuideSelect extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.props.dispatch(fetchOrderGuides());
}
selectOrderGuide = id => {
this.props.dispatch(orderGuideSelected(id));
}
render() {
const {isLoading, orderGuides} = this.props.orderGuide;
return (
<View style={styles.wrapper}>
<Header />
<View style={styles.iconLine}>
<MBIcon name='ico-24-filter' style={styles.filterIcon} />
</View>
{isLoading &&
<ActivityIndicator
style={{alignSelf: 'center'}}
animating={true}
size='large'
/>
}
{!isLoading &&
<View style={styles.optionList}>
<FlatList
style={styles.optionList}
data={orderGuides}
keyExtractor={(item, index) => item.id.toString()}
renderItem={({item}) => <OrderGuideOption guideData={item} isSelected={item.id == this.props.selectedGuide.id} onSelected={this.selectOrderGuide} />}
/>
</View>
}
</View>
);
}
}
function mapStateToProps(state){
const {products, orderGuide} = state;
return {
selectedGuide: products.selectedOrderGuide,
orderGuide
}
}
export default connect(mapStateToProps)(OrderGuideSelect);
Also, I may be importing of the OrderGuideSelect component should be correct:

In your code calling this.renderOrderGuideOptions function on onPress event doesn't make sense, i.e. this.renderOrderGuideOptions returns the element but where to append it in DOM?
This should be achived using state in React. So you can set the state in onPress handler then use that state in render to show your OrderGuideOptions component.
So on onPress event bind the function handler:
<TouchableOpacity onPress={this.showOrderGuideOptions}>
<MBIcon name="ico-24-filter" size={30} style={styles.filterIcon}/>
</TouchableOpacity>
Now this showOrderGuideOptions will set the state named showOrderGuideFunction to true.
showOrderGuideOptions(){
this.setState({showOrderGuideFunction: true});
}
At last step use this showOrderGuideFunction state to render your component in the render function like this:
render() {
return (
<div>
...
{
this.state.showOrderGuideFunction &&
renderOrderGuideOptions()
}
</div>
)
}

You can do what you want probably holding a state property in your component and show your OrderGuideOptions according to this state property.
state = { showOrderGuideOptions: false };
renderOrderGuideOptions = () =>
this.setState( prevState => ( { showOrderGuideOptions: !prevState.showOrderGuideOptions }) );
render() {
return (
<View>
<TouchableOpacity onPress={this.renderOrderGuideOptions}>
<MBIcon name="ico-24-filter" size={30} style={styles.filterIcon}/>
</TouchableOpacity>
{ this.state.showOrderGuideOptions && <OrderGuideSelect /> }
</View>
)
}

I think you wanted to something similar to this
class RenderOrderGuideSelectComponent extends Component {
constructor(props) {
super(props);
this.state={
showOrderGuideSelect : false
};
}
renderOrderGuideOptions = () => {
this.setState({showOrderGuideSelect: true});
}
render() {
if(this.state.showOrderGuideSelect) {
return (
);
} else {
return (
this.renderOrderGuideOptions()}>
);
}
}
}

Related

Calling a custom hook with a parameter from a custom component

I have this custom hook I want to be executed when pressing a button inside a custom component
import { useDispatch } from 'react-redux';
import { useCallback } from 'react';
import { retireUserFromEvents } from '../../../redux/actions/Events';
export default function useDeleteAssistantToEvent() {
const dispatch = useDispatch();
const deleteAssistantToEvent = useCallback(userID => {
dispatch(retireUserFromEvents(userID));
}, [dispatch]);
return deleteAssistantToEvent;
}
I declare the hook on the screen where the custom component is:
import {
AttendantList
} from '../../../../components';
import useDeleteAssistantToEvent from '../../../../hooks/assistance/useDeleteAssistantToEvent';
export default function EventAssistantsView({ navigation }) {
const deleteAssistant = useDeleteAssistantToEvent();
return (
<SafeAreaProvider>
<SafeAreaView style={styles.safeAreaViewStyle}>
<View style={styles.mainViewStyle}>
<AttendantList
...
undoInvite={() => deleteAssistant}
/>
</View>
</SafeAreaView>
</SafeAreaProvider>
);
}
And this is my custom component (AttendantList):
export default function AttendantList({ attendees, goToUserProfile, undoInvite, imHostOrCohost }) {
return (
<View style={styles.mainViewStyle}>
{attendees.length > 0 ? (
<FlatList
...
renderItem={({ item }) => (
<TouchableOpacity onPress={goToUserProfile()}>
<InviteCard
...
onPress={() => undoInvite(item.id)}
/>
</TouchableOpacity>
)}
/>
) : (
...
)}
</View>
);
}
ÌnviteCard is the button in question.
The problem is that, anytime I want to press the button, nothing happens. So, how can I pass the hook call to the custom component?

React Native: Basic FlatList to render API content

I am trying to render data from an API using a FlatList.
I can't get anywhere. I have a lot of trouble filling in the DATA and renderItem fields.
Could you help me ?
Thank you :)
import React from "react";
import { Text, ActivityIndicator, FlatList, View } from "react-native";
import axios from "axios";
export default class Results extends React.Component {
constructor(props) {
super(props);
//console.log('state',this.props)
this.state = {
city: "Montpellier", //this.props.city,
report: null, // Données de l'API
};
this.fetchWeather();
}
fetchWeather() {
axios
.get(
"https://api.openweathermap.org/data/2.5/weather?q=" +
this.state.city +
"&appid=9fce19ee0d267aa48afdf331bb1668da",
)
.then((response) => {
this.setState({ report: response.data });
//console.log(response.data)
});
}
render() {
const DATA = this.state.report;
if (this.state.report === null) {
return <ActivityIndicator size="large" color="red" />;
} else {
return (
<FlatList data={DATA} renderItem={<Text> {this.state.report.id} </Text>} keyExtractor={(item) => item.id} />
);
}
}
}
renderItem prop basically passes each item in your data to the function provided so that you can render them accordingly in the list. Changing you flatlist like this should work.
render() {
const {report} = this.state;
if (report === null) {
return <ActivityIndicator size="large" color="red" />;
} else {
return (
<FlatList
data={report}
renderItem={(reportItem) => <Text> {reportItem.id} </Text>}
keyExtractor={(item) => item.id} />
);
}
}
There are two mistakes in your Flatlist.
renderItem must be a function that returns all your JSX code
Since you already provided the Flatlist with data, you don't need to refer to this.state.report.id again, you can simply replace it with {item.id}.
So your Flatlist should look like this:
<FlatList
data={DATA}
keyExtractor={(item) => item.id}
renderItem={(item) => {
return (
<Text> {item.id} </Text>)
}}
</FlatList>
So the idea is that the FlatList will take in an array (<FlatList data={DATA} ...) and will automatically go through the items one by one. But it does not know how to render the actual UI for each item. For that we are giving a function which will transform each item into a UI element. This is the function that we are missing.
So
import React from "react";
import { Text, ActivityIndicator, FlatList, View } from "react-native";
import axios from "axios";
export default class Results extends React.Component {
.
.
.
render() {
const DATA = this.state.report;
if (this.state.report === null) {
return <ActivityIndicator size="large" color="red" />;
} else {
return (
<FlatList data={DATA} renderItem={function (item) {
return <Text> {item.id} </Text>
}} keyExtractor={(item) => item.id} />
);
}
}
}
As per the documentation, what they mean is that this function will be called and each item will be passed into it. The item shape will be of the same shape as DATA[0] (essentially any object in that array).
In the docs, they have this snippet,
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
This essentially means that each object in the array is of shape
{
title: "some title"
}
That is called object destructuring, and it is easy to understand if you google for it :)

How to refresh main App class rendering in React-Native from another class

I'm trying to create my first App using React-Native,
i've created a class which renders the authentication form, after handling the submit the App should render the Navigation Screen with its tabs. I think i can "refresh" in someway the App class rendering from the Authentication Screen so it can check again if the user has authenticated or not, but i'm not really sure
App.Js:
import AuthScreen from './screens/AuthScreen';
export default class App extends React.Component {
state = {
isLoadingComplete: false,
isAuthenticated: false,
};
render() {
if (!this.state.isLoadingComplete && !this.props.skipLoadingScreen) {
return (
<AppLoading
startAsync={this._loadResourcesAsync}
onError={this._handleLoadingError}
onFinish={this._handleFinishLoading}
/>
);
} else {
if(this.state.isAuthenticated == true) {
return (
<View style={styles.container}>
<StatusBar hidden = {true} />
<AppNavigator />
</View>
);
} else {
return (
<View style={styles.container}>
<StatusBar hidden = {true} />
<AuthScreen />
</View>
);
}
}
}
AuthScreen.js:
export default class AuthScreen extends Component {
handleSubmit = () => {
const value = this._form.getValue();
console.log('value: ', value);
}
render() {
return (
<View style={styles.container}>
<View style={styles.auth_container}>
<Form
ref={c => this._form = c}
type={User}
options={options}
/>
<Button
title="Submit"
onPress={this.handleSubmit}
/>
</View>
</View>
);
}
}
You can do this by using react-navigation(RN navigation library). But per code in question your trying to toggle between screen.
In your way: handleSubmit method of AuthScreen if success to following
handleSubmit = () => {
check auth logic
this.props.onSuccessFullLogin(value)
}
Update State in ParentComponent to toggle between screens App Component:
<AuthScreen /> this should be like <AuthScreen onSuccessFullLogin={()=>this.setState({isAuthenticated:true})} />

DatePickerIOS nothing happen

When i try to use DatePickerIOS with react native nothing happen in my phone ...
my code :
import React, { Component } from 'react';
import {Text, View, DatePickerIOS} from 'react-native';
export default class DatePicker extends Component {
constructor(props) {
super(props);
this.state = {
today: new Date(),
}
}
render() {
return (
<View>
<DatePickerIOS date={this.state.today} mode="time" onDateChange={(value) => this.setState({today: value})}/>
</View>
);
}
}
SomeOn know why ?
If you want to print selected time in the UI add the following to the render
render() {
return (
<View>
<DatePickerIOS
date={this.state.today}
mode="time"
onDateChange={(value) => this.setState({today: value})}
/>
<Text>{this.state.today.toTimeString()}</Text>
</View>
);
}

React Natve Showing Text Box onPress?

import React, { Component } from 'react';
import { AppRegistry, Text, View, TouchableOpacity } from 'react-native';
class Check extends Component {
constructor(props){
super(props);
this.pressed = true
}
_callme = () => {
if(!this.pressed){
return ( <View>
<TouchableOpacity onPress={this._callMe}>
Show me TextBox
</TouchableOpacity>
</View>
)
}
else{
return (
<View>
<TextInput />
</View>)
}
}
showText = () => {
return (
<TouchableOpacity on Press={this._callMe}>
<Text>Show me TextBox</Text>
</TouchableOpacity>
)
}
render() {
return(
<View>
{this.pressed ? this._callMe : this.showText}
</View>
)
}
}
AppRegistry.registerComponent('Check', () => Check);
I am Newbie into the ReactNative, what I want is when ever a user clicks on a button user should get a popup box for comment, but I don't know where I am doing wrong?
Since you want to render the returned value, you need to call the function with ()
{this.pressed ? this._callMe() : this.showText()}
Also showText function return component <TouchableOpacity on Press={this._callMe}> has a space between on Press change to onPress.

Resources