React Native - render a component onClick on an Icon - reactjs

A part of my app has an 'icon'. When I 'click' on the icon, the State of the parent component changes to 'true' and I want a new 'Component' to render saying 'I am a new Component'. I am trying like this below, there is no error showing at the debugger. The Icon is an image component that I am importing. Here is the Code.
This is the parent Component
import React, {Component} from 'react';
import {View} from 'react-native';
import {Icon} from '../ui/Icon';
type HomeSceneState = {
calendarState:boolean
}
class HomeScene extends Component<HomeSceneState> {
state = {
calendarState:false
}
openCalendar = () => {
console.log("open calendar")
this.setState({
calendarState : true
})
}
render() {
return (
<View style={{marginBottom: spacing.double,
backgroundColor:"black", flexDirection:"row"
}}>
<View>
<Icon onPress = {() => this.openCalendar()} />
{this.calendarState ? <Casie/> : null }
</View>
</View>
);
}
}
export default HomeScene;
The Children Component looks like below
class Casie extends Component<CalendarProps> {
render() {
return (
<View>
I am a new Component
</View>
);
}
}
export default Casie;

replace <Calendar/> by your child component name <Casie/> (in your case). It seems you are not rendering your child component when the state changes.

In your parent component you import the react native navigation.
after you can use useNavigation for navigate the page. Sorry my english.
import { useNavigation } from '#react-navigation/native'
class HomeScene extends Component<HomeSceneState> {
state = {
calendarState:false
}
openCalendar = () => {
console.log("open calendar")
navigation.navigate('Casie')
}
render() {
return (...)
}
}
export default HomeScene;

Related

what is best way to get props in React / React Native

I'm really regarding props in React/React-Native. I have a parent view. In this view I'm getting the user data from a LocalStorage.['
import React, { Component } from 'react';
import { Container, Content, View } from 'native-base';
import NutrionalToolbar from '../../components/NutrionalToolbar';
import { AsyncStorage } from 'react-native';
export default class LogsScreen extends Component {
state = {
user: '',
}
componentWillMount() {
this._bootstrapAsync();
}
_bootstrapAsync = async () => {
const user = await AsyncStorage.getItem('user');
this.setState({ user: JSON.parse(user) })
};
render() {
return (
<Container>
<NutrionalToolbar user={this.state.user} />
</Container>
);
}
}
Now inside the NutrionalToolbar component I have this.
import React, { Component } from 'react';
import { View } from 'native-base';
class NutrionalToolbar extends Component {
constructor(props) {
super(props)
console.log(this.props) // This renders an empty user object
}
render() {
console.log(this.props) // This renders the user object with values
return (
<View>
</View>
);
}
}
export default NutrionalToolbar;
How can I get this.props values inside the constructor. I'm getting the values inside render method. Why isn't working inside the constructor?
I would recommend looking into the componentDidUpdate lifecycle hook because, even if you could access the initial user prop in the constructor, you wouldn't be able to access updates to that prop in the constructor.
import React, { Component } from 'react';
import { View } from 'native-base';
class NutrionalToolbar extends Component {
componentDidUpdate() {
console.log(this.props) // This will always log the current props
}
render() {
return (<View></View>);
}
}
export default NutrionalToolbar;

Initialize react-native application with class components

I have just installed create-react-native-app and created one. I can see that app is a function there
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
</View>
);
}
I know that both Functional and Class-Components in available in React. Now I want to create app with Class Components. Can somebody suggest how to do it?
For people who come from heavy object-oriented background, the class-based component will let them jump on reactjs relatively quickly compared to a functional-based component.
Here is some basic skeleton of the class component:
import * as React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
export default class App extends React.PureComponent {
constructor() {
// Where you initialize some data
}
componentDidMount() {
// Lifecycle method when your component is mounted
}
componentWillUnmount() {
// Lifecycle method when your component is unmounted
}
_handleOnButtonPress = () => {
// Handler when your button is pressed
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this._handleOnButtonPress}>
<Text>Open up App.tsx to start working on your app!</Text>
</TouchableOpacity>
</View>
);
}
}
And here is a further reference to compare class and functional component. Cheers!
Here is code for you :
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet
} from 'react-native';
class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount = () => {
// initial method
};
render() {
return (
<View>
<Text>Test</Text>
</View>
);
}
}
const styles = StyleSheet.create({
});
export default App;
You don't need to make it a class unless you are using state in the class

FlatList in react native is rendering but not showing text

I'm trying to render a flatlist by connecting to a internal JSON file. The flatlist seems to be rendering but not showing any text. The cardlist in the code is being rendered 9 times, there are 9 objects in the JSON file. But no text is showing.
// libraryList.js
import React, { Component } from 'react';
import { FlatList } from 'react-native';
import { connect } from 'react-redux';
import ListItem from './ListItem';
class LibraryList extends Component {
renderItem(library) {
return <ListItem library={library} />;
}
render() {
// console.log(this.props);
// return;
return (
<FlatList
data={this.props.libraries}
renderItem={this.renderItem}
keyExtractor={library => library.id}
/>
);
}
}
const mapStateToProps = state => {
return { libraries: state.libraries };
};
export default connect(mapStateToProps)(LibraryList);
// ListItem.js
import React, { Component } from 'react';
import { Text } from 'react-native';
import { CardSection } from './common';
class ListItem extends Component {
render() {
return (
<CardSection>
<Text>{this.props.library.title}</Text>
</CardSection>
);
}
}
export default ListItem;
import React, { Component } from 'react';
import { Text } from 'react-native';
import { CardSection } from './common';
class ListItem extends Component {
render() {
return (
<CardSection>
<Text>{this.props.library.title}</Text>
</CardSection>
);
}
}
export default ListItem;
Just want to list the title at this stage.
You need to modify renderItem because FlatList passes an object into the renderItem callback function.
Instead, use the below
renderItem = ({ item }) => <ListItem library={item} />
Thanks Dan you put me onto the right lines. I used
renderItem={({ item }) => this.renderItem(item)}

React native set state is not working

I am trying to update state in react native component.
But its getting errors, Could someone help me.
I'm using react-native-cli verions: 2.0.1
react-native verions: 0.55.4
Here is my code:
import React, { Component } from 'react'
import {
Button,
Text,
View,
} from 'react-native';
export class ToggleButton extends Component {
state = {
isDone: false
};
onAction() {
const value = !this.state.isDone;
this.setState({ isDone: value });
const newValue = this.state.isDone;
console.log(newValue);
}
render() {
return (
<View>
<Button
title="Action"
onPress={this.onAction}
/>
</View>
)
}
}
export default ToggleButton;
You have three different solutions.
Bind your function in the constructor.
Use the experimental public class fields syntax.
Pass a lambda to executing your function.
The problem is that you're loosing the reference to this, because the function is not executed in the original context, so this.setState is not a function, but a undefined.
In this page there are examples for all of the approaches: https://reactjs.org/docs/handling-events.html
Change
onPress={this.onAction}
to
onPress={this.onAction.bind(this)}
Check: this
Below is the solution
import React, { Component } from 'react'
import {
Button,
Text,
View,
} from 'react-native';
export class ToggleButton extends Component {
// Add state in constructor like this
constructor(props){
super(props);
this.state = {
isDone: false
};
}
onAction() {
const value = !this.state.isDone;
this.setState({ isDone: value });
const newValue = this.state.isDone;
console.log(newValue);
}
render() {
return (
<View>
<Button
title="Action"
// Add function with onPress
onPress={() => this.onAction}
/>
</View>
)
}
}
export default ToggleButton;

Navigate to completely different screen on React Native

On my React Native app I am initially loading SceneA, which simply displays a text "Click me". When this button is clicked I would like to load a completely different screen (SceneB) that has completely different components.
All the examples that I found online (like the example below) load a scene with exactly the same components, but different values. In my case it is a completely different layout. How can I navigate to that new screen (SceneB)?
It is basically the equivalent to a new Activity on Android, passing some data at the same time. Any pointers will be appreciated.
index.android.js
import React, { Component } from 'react';
import { AppRegistry, Navigator } from 'react-native';
import SceneA from './SceneA';
class ReactNativeTest extends Component {
render() {
return (
<Navigator
initialRoute={{ title: 'My Initial Scene', index: 0 }}
renderScene={(route, navigator) =>
<SceneA
title={route.title}
// Function to call when a new scene should be displayed
loadNewScene={() => {
const nextIndex = route.index + 1;
navigator.push({
title: 'Scene B',
index: nextIndex,
});
}}
/>
}
/>
)
}
}
AppRegistry.registerComponent('ReactNativeTest', () => ReactNativeTest);
SceneA.js
import React, { Component, PropTypes } from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
export default class SceneA extends Component {
render() {
return (
<View>
<Text>Scene A</Text>
<TouchableHighlight onPress={this.props.loadNewScene}>
<Text>Click Me</Text>
</TouchableHighlight>
</View>
)
}
}
SceneA.propTypes = {
loadNewScene: PropTypes.func.isRequired,
};
You handle which components should render in the renderScene function, each scene will have a route.title so you can decide which to render based on that.
renderScene={(route, navigator) =>
if (route.title === 'Scene A') {
return <SceneA navigator={navigator} />
}
if (route.title === 'Scene B') {
return <SceneB navigator={navigator} />
}
}
Then inside your components you're gonna have a function that handles the navigation:
navigateToSceneB = () => {
this.props.navigator.push({
title: 'Scene B'
})
}

Resources