I am trying to learn React Native and want to make text that changes color every second. I have this code, but my ios emulator just shows a blank white screen with no text at all. Can someone take a look at the code below and tell me what I did wrong?
Thank You!
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<ChangeColor text= 'This text should be changing color.'/>
<ChangeColor text= 'Hopefully it works.'/>
</View>
);
}
}
class ChangeColor extends React.Component {
constructor(props) {
super(props);
this.state = {color: StyleSheet.skyBlue};
// Toggle the state every second
setInterval(() => {
this.setState(
{ color: StyleSheet.steelBlue}
);
}, 1000);
}
render() {
let display = this.state.color ? this.props.text : ' ';
return (
<Text>{display}</Text>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
skyBlue: {
color: 'skyblue',
},
steelBlue: {
color: 'steelblue',
},
});
Take a look at this snack: https://snack.expo.io/rkFe9tpfQ
StyleSheet.steelBlue
becomes
styles.steelBlue
Related
I am pretty new to react native and am trying to get the home page of my first basic app to load. Currently, it asks users to input their "name" and "networth" and I simply want to return the networth input multiplied by a constant with an alert that appears after pressing submit saying "{name} + " net worth will be " + {newNetworth} + " next year!". However right now my output is: "undefined will be worth undefined next year!" and I cannot figure out for the life of me how to get the actual values to pass through.
Here is my child component:
import React from 'react';
import { View, Text, TouchableOpacity, TextInput, StyleSheet } from 'react-native';
class OpeningPageQs extends React.Component {
state = {
name: '',
networth: 0,
newNetworth: 0
}
nextYearWorth() {
this.setState({
name: this.state.name,
newNetworth: this.state.networth * 1.1
});
return (alert(this.name + ' will be worth ' + this.newNetworth + ' next year!'));
}
render (){
return (
<View>
<TextInput style= { styles.input }
placeholder= "name"
onChangeText= { this.name }
/>
<TextInput style= { styles.input }
placeholder= 'networth'
onChangeText= { this.networth }
/>
<TouchableOpacity style = {styles.submitButton}
onPress = {
() => this.nextYearWorth(this.state.name, this.state.networth)
}
>
<Text style={styles.submitButtonText}>
Submit
</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
paddingTop: 23
},
input: {
margin: 15,
height: 40,
borderColor: '#7a42f4',
borderWidth: 1
},
submitButton: {
backgroundColor: '#7a42f4',
padding: 10,
margin: 15,
height: 40,
},
submitButtonText: {
color: 'white'
}
})
export default OpeningPageQs;
And here is my Parent component:
import { StatusBar } from 'expo-status-bar';
import React, { useState, Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import OpeningPageQs from './components/OpeningPageQs';
export default class App extends React.Component {
constructor (props){
super(props);
//building initial state for input props
this.state = {
name: '',
networth: this.networth
};
}
render(){
return (
<View style={styles.container}>
<StatusBar style="auto" />
<OpeningPageQs
name={this.state.name}
networth={this.state.networth}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Any help would be greatly appreciated
Reffering to: https://reactnative.dev/docs/textinput
You are wrongly setting the state. Try like this:
<TextInput style= { styles.input }
placeholder= "name"
onChangeText={text => this.setState({name: text})}
/>
It may be worth not setting the state just to show the results. You can either create local variable in nextYearWorth method, or multiple the value when setting the state inside onChangeText callback.
For the alert - please take a look at Modal component: https://reactnative.dev/docs/modal#docsNav
You can use like that.
<TextInput style= { styles.input }
placeholder= "name"
onChangeText= { text => this.name = text }
/>
I'm working on an app in React Native. I want to make it so the styling of the panel labels on the bottom of the screen updates based on the panel the user is on.
As of now, I can get the index of the current panel that's showing, but I don't know how to make that update the styling of the labels.
The first panel
and the second panel
Basically when you use the same component and want to style it in different ways, your component's style property depends on either props or state. There are many ways to put different styles depending on your state/props, I'll provide just a few of them:
Ternary operation based on current state.
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const styles = StyleSheet.create({ // Your styles go here
labelFirstTab: {
textColor: 'red',
},
labelSecondTab: {
textColor: 'blue',
},
});
class MyApp extends React.Component {
state = {
currentTab: 0,
};
getLabelStyles = () => {
const { currentTab } = this.state;
return currentTab === 0 ? styles.labelFirstTab : styles.labelSecondTab;
};
render() {
return (
<View style={{ flex: 1 }}>
{/* Let's say this is your label */}
<Text style={this.getLabelStyles()}>Hi! I'm a nice label.</Text>
</View>
);
}
}
Additional styling based on props (also could depend on state, it doesn't matter).
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
label: {
fontSize: 16,
textColor: 'black',
},
labelDarkMode: {
textColor: 'lightgrey',
},
}); // Your styles go here
class MyApp extends React.Component {
getLabelStyles = () => {
const { isDarkMode } = this.props;
const { label, labelDarkMode } = styles;
return [styles.label, isDarkMode && styles.labelDarkMode];
};
render() {
return (
<View style={{ flex: 1 }}>
{/* Let's say this is your label */}
<Text style={this.getLabelStyles()}>Hi! I'm a nice label.</Text>
</View>
);
}
}
You even can pass your styles directly from your props, leaving the whole logic to your parent component. Just make sure that you've passed styles from your parent component to the current one.
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
class MyApp extends React.Component {
render() {
const { labelStyles } = this.props;
return (
<View style={{ flex: 1 }}>
{/* Let's say this is your label */}
<Text style={labelStyles}>Hi! I'm a nice label.</Text>
</View>
);
}
}
Thank you E. Dn! This worked! Here's what I did.
const [activePanel, setActivePanel] = useState('nowPanel');
Swiping between panels calls a function:
const swipeNavigation = (index) => {
if (index === 0) {
setActivePanel('nowPanel');
} else {
setActivePanel('todayPanel');
}
};
Then within the actual View I want to style:
style={activePanel === 'nowPanel' ? styles.activePanel : null,}>
I'm trying to make a custom router component, that will pick a layout dynamically. But, when I'm trying to render layout dynamically I receive blank page.
What I'm doing wrong?
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import WelcomePageLayout from '../layouts/welcome-page';
import GamePageLayout from '../layouts/game';
export default class Router extends Component {
constructor(props) {
super(props);
this.layouts = [
WelcomePageLayout,
GamePageLayout
];
this.state = {
currentLayout: 0
};
}
render() {
const layout = this.layouts[this.state.currentLayout];
return (
<View style={styles.container}>
{ layout }
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
flex: 1,
paddingTop: 60,
alignItems: 'center',
justifyContent: 'center',
marginBottom: 100
}
});
A step ago, before adding this dynamic render everything was working as expected. So I'm pretty sure it's something about that.
Thanks in advance.
You are just passing the component as a child to View. Make sure you render it as well:
render() {
const Layout = this.layouts[this.state.currentLayout];
return (
<View style={styles.container}>
<Layout />
</View>
);
}
Note: I am new to React Native and have searched up how to do this but found no helpful results I am using React Native to create an app and want to add multiple components, such as text, buttons, and a text input space, but am having trouble doing so without receiving errors. Is there any way to include multiple components into one javascript document using React Native?
The code I currently have:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Text style={styles.bigblack}>Sample Bold Text Here</Text>
<Text>Sample Text Here:</Text>
</View>
);
}
}
const styles = StyleSheet.create({
bigblack: {
color: 'black',
fontWeight: 'bold',
fontSize: 28,
},
red: {
color: 'red',
},
container: {
flex: 1,
backgroundColor: '#fdf5e6',
alignItems: 'center',
justifyContent: 'center',
},
});
Code I want to add for Text Input:
class UselessTextInput extends Component {
render() {
return (
<TextInput
{...this.props}
editable = {true}
maxLength = {40}
/>
);
}
}
export default class UselessTextInputMultiline extends Component {
constructor(props) {
super(props);
this.state = {
text: 'Useless Multiline Placeholder',
};
}
render() {
return (
<View style={{
backgroundColor: this.state.text,
borderBottomColor: '#000000',
borderBottomWidth: 1 }}
>
<UselessTextInput
multiline = {true}
numberOfLines = {4}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
</View>
);
}
}
Code I want to add for Button:
<Button
onPress={onPressLearnMore}
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this button"
/>
You can create multiple component in same document but can export default only one.
So you can create multiple component like below:
export class UselessTextInput {}
export class UselessTextInputMultiline {}
export class Button {}
while accessing :
import {UselessTextInput, UselessTextInputMultiline, Button} from './components/customInput' // change with your respective path
if you still want to have single export default then:
export default class UselessTextInputMultiline {}
and while importing
import Template,{Button} from './components/customInput'
For, exporting multiple component:
module.exports = {
text: UselessTextInput,
btn: Button
}
imports will be like:
let txtInput= require('./components/customInput').text;
let btnInput = require('./components/customInput').btn;
So consider the following:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity
} from 'react-native';
class CreateTweet extends Component {
getInitialState() {
return {
text: 'Fake Value'
}
}
render() {
console.log(this.state);
return(
<View style={styles.container}>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 100,
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
AppRegistry.registerComponent('CreateTweet', () => CreateTweet);
module.exports = CreateTweet;
When run the state is null. You can see the console.log(this.state) I am setting the state when the component is initialized, What is going on? Is there some magic I don't know about in React native thats different then React?
Since you are using classes, your state should be set up in a constructor:
constructor (props) {
super(props)
this.state = {
text: 'Fake Value'
}
}