I'm reading Learning React Native by Bonnie Eisenman and am having trouble with the WeatherProject tutorial in chapter 3. When the app loads in the iOS simulator, it appears to be rendering the contents of Forecast.js but taking up the whole display without anything from WeatherProject.js
Here is my code:
index.ios.js
import {
AppRegistry,
} from 'react-native';
import WeatherProject from './WeatherProject';
AppRegistry.registerComponent('WeatherProject', () => WeatherProject);
WeatherProject.js
import React, {
Component,
} from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
} from 'react-native';
var Forecast = require('./Forecast');
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#4D4D4D'
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10
},
input: {
fontSize: 20,
borderWidth: 2,
height: 40
}
});
var WeatherProject = React.createClass({
getInitialState() {
return {
zip: '',
forecast: {
main: 'Clouds',
description: 'few clouds',
temp: 45.7
}
}
},
_handleTextChange(event) {
console.log(event.nativeEvent.text);
this.setState({
zip: event.nativeEvent.text
});
},
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
You input {this.state.zip}.
</Text>
<Forecast
main={this.state.forecast.main}
description={this.state.forecast.description}
temp={this.state.forecast.temp}/>
<TextInput
style={styles.input}
returnKeyType="go"
onSubmitEditing={this._handleTextChange}/>
</View>
);
}
});
module.exports = WeatherProject;
Forecast.js
import React, {
Component,
} from 'react';
import {
StyleSheet,
Text,
View,
} from 'react-native';
var styles = StyleSheet.create({
bigText: {
flex: 2,
fontSize: 20,
textAlign: 'center',
margin: 10,
color: '#FFFFFF'
},
mainText: {
flex: 1,
fontSize: 16,
textAlign: 'center',
color: '#FFFFFF'
}
});
var Forecast = React.createClass({
render() {
return (
<View>
<Text style={styles.bigText}>
{this.props.main}
</Text>
<Text style={styles.mainText}>
Current conditions: {this.props.description}
</Text>
<Text style={styles.bigText}>
{this.props.temp}°F
</Text>
</View>
);
}
});
module.exports = Forecast;
The expected outcome looks like this (from the book):
But my actual outcome is this:
And here is the view debug hierarchy:
Any help at all would be greatly appreciated.
Add this style in Forecast:
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
then add the style into the View:
<View styles={style.container}>
Related
I am new to CSS skills.
I didn't learn much about it.
I have a question about how to make an element have full width.
I added my code down below, but the simplest way I tried didn't work which is width: '100%'.
I have a code in react native, so components are nested in order I put. The higher code is a parent of code right down to it.
I would like elements in RideCard.js, each ride card, to have expand fully next to DateDay.js. I could have seen that once I removed flexDirection: row in oneDayContainer in MonthBody.js, the elements expanded fully.
But I would like to keep the design.
Thanks in advance.
MonthBody > DateDay + RideList >
MonthBody.js
import { StyleSheet } from "react-native";
import { View } from "react-native";
import { useFirestoreContext } from "../../contexts/FirestoreContext";
import { DateDay } from "./DateDay";
import { RideList } from "./RideList";
export const MonthBody = ({ monthYear }) => {
const { rides } =
useFirestoreContext();
return (
<View style={styles.monthBodyContainer}>
{Object.keys(rides[monthYear]).map((dateDay, j) => {
return (
<View style={styles.oneDayContainer}>
<DateDay dateDay={dateDay} />
<RideList monthYear={monthYear} dateDay={dateDay} />
</View>
);d
})}
</View>
);
}
const styles = StyleSheet.create({
monthBodyContainer: {
display: "flex",
flexDirection: "column",
},
oneDayContainer: {
display: "flex",
flexDirection: "row",
alignItems: "flex-start",
},
});
DateDay.js
import { StyleSheet, Text, View } from "react-native";
export const DateDay = ({dateDay}) => {
return (
<View style={styles.dateDayContainer}>
<Text style={styles.dayText}>{dateDay.split("-")[1]}</Text>
<Text style={styles.dateText}>{dateDay.split("-")[0]}</Text>
</View>
);
};
const styles = StyleSheet.create({
dateDayContainer: {
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
width: 50,
marginRight: 20,
marginTop: 10,
},
dateText: {
fontSize: 16,
textAlign: "center",
},
dayText: {
fontSize: 12,
textAlign: "center",
},
});
RideList.js
import { StyleSheet, Text, View } from "react-native";
import { COLOR } from "../../assets/variables";
import { useFirestoreContext } from "../../contexts/FirestoreContext";
import { RideCard } from "./RideCard";
export const RideList = ({ monthYear, dateDay }) => {
const { rides } = useFirestoreContext();
return (
<View style={styles.rideList}>
{rides[monthYear][dateDay].map((ride, k) => {
// return <RideCard key={k} ride={ride} />;
return <RideCard key={k} ride={ride} />;
})}
</View>
);
};
const styles = StyleSheet.create({
rideList: {
marginBottom: 5,
},
});
RideCard.js
import { StyleSheet, Text, View } from "react-native";
import { COLOR } from "../../assets/variables";
export const RideCard = ({ ride }) => {
console.log("RideCard", ride);
return (
<View
style={[
styles.container,
ride.boardType === "NEED"
? { backgroundColor: COLOR.lightGreen, borderWidth: .3, borderColor: COLOR.green }
: { backgroundColor: COLOR.lightBlue, borderWidth: .3, borderColor: COLOR.blue },
]}
>
<View style={styles.places}>
<Text style={styles.placeText}>{ride.cityFrom}</Text>
<Text> - </Text>
<Text style={styles.placeText}>{ride.cityTo}</Text>
</View>
<View>
<Text style={styles.dateText}>
{ride.leavingHour}:{ride.leavingMinutes}
</Text>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 10,
marginBottom: 5,
borderRadius: 10,
},
places: {
display: "flex",
flexDirection: "row",
alignItems: "center",
marginBottom: 5,
},
});
On the CardList styles you can add flex: 1 to the rideList.
const styles = StyleSheet.create({
rideList: {
marginBottom: 5,
flex: 1,
},
});
I'm creating onBoarding screens and I have created each of the screen item as a component and trying to render them with Flatlist so far everything is working smoothly but when I swipe the flatlist to see the other screens it's not working it swipes 40% and and forcefully shows the current screen it seems like there is some flex styling issues and I could able to figure it out please suggest.
Here is the video for explaination: https://youtube.com/shorts/pHbTs7ifMww
OnBoardingScreen.js
import React, { useState } from 'react';
import { Dimensions, FlatList, SafeAreaView, View, StyleSheet, Text, Image } from 'react-native';
const { width, height } = Dimensions.get('window');
const COLORS = {primary : '#ff006c', white: '#ffffff', black: '#000000'};
const slides = [
{
id: '1',
image: require('../../images/OnBoardingImages/1.png'),
title: 'You can mark time',
description: 'Lorem ipsum is a placeholder text commonly used to demonstrate the visual',
},
{
id: '2',
image: require('../../images/OnBoardingImages/2.png'),
title: 'You can mark time',
description: 'Lorem ipsum is a placeholder text commonly used to demonstrate the visual',
},
{
id: '3',
image: require('../../images/OnBoardingImages/3.png'),
title: 'You can mark time',
description: 'Lorem ipsum is a placeholder text commonly used to demonstrate the visual',
},
]
const Slide = ({item}) => {
return (
<View style={styles.slideView}>
<Image source={item.image} style={styles.slideImage} />
<Text style={styles.slideTitle}>{item.title}</Text>
<Text style={styles.slideDescription}>{item.description}</Text>
</View>
);
}
const OnBoardingScreen = ({ navigation }) => {
const [currentSlideIndex, setCurrentSlideIndex] = useState(0);
const Footer = () => {
return (
<View style={styles.footer}>
<View style={styles.pagination}>
{slides.map((_, index) => (<View key={index} style={[styles.paginationItem, currentSlideIndex == index && {backgroundColor: 'grey'} ]} /> ))}
</View>
</View>
);
};
return (
<SafeAreaView style={styles.root}>
<FlatList
data={slides}
contentContainerStyle={{flex: 1}}
showsHorizontalScrollIndicator={false}
horizontal
pagingEnabled
renderItem={({item}) => <Slide item={item} />} />
<Footer />
</SafeAreaView>
);
};
export default OnBoardingScreen;
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: COLORS.white,
},
slideView: {
alignItems: 'center',
},
slideImage: {
height: '75%',
width: width,
resizeMode: 'contain',
},
slideTitle: {
color: COLORS.primary,
fontSize: '22',
fontWeight: 'bold',
marginVertical: 10,
paddingHorizontal: 10,
textAlign: 'center',
},
slideDescription: {
fontSize: 18,
paddingHorizontal: 20,
color: 'grey',
textAlign: 'center',
},
footer: {
height: height * 0.25,
paddingHorizontal: 20,
justifyContent: 'space-between',
},
pagination: {
flexDirection: 'row',
justifyContent: 'center',
marginTop: 20,
},
paginationItem: {
height: 10,
width: 10,
backgroundColor: COLORS.primary,
marginHorizontal: 3,
borderRadius: 50,
},
});
App.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import Navigation from './src/navigation';
export default function App() {
return (
<View style={styles.container}>
<Navigation />
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
Update this style
slideView: {
alignItems: 'center',
width: width
},
I'm learning React Native and need help from the React Native experts out there! Does anyone know how to redirect a link to new page(component).
I have a list of items (Purchases, Settings, Polices, Customer Support) that I want to redirect them to a new page when I click on it. Do I need to use the onPress event or is there another way?
import React, { component} from 'react';
import {Component} from 'react';
import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native';
import Login from './LogIn';
class Profile extends Component{
state = {
names: [
{
id: 0,
name: 'Purchases',
},
{
id: 1,
name: 'Settings',
},
{
id: 2,
name: 'Policies',
},
{
id: 3,
name: 'Feedback',
},
{
id: 3,
name: 'Customer support',
},
{
id: 3,
name: 'About the app',
}
]
}
render(){
return(
<View style={styles.container}>
<Text style={styles.header}>Welcome to GOLDENSHOE</Text>
<Text style={{fontSize: 16}}>Sign up or log in to access special discounts, your favorites and your account </Text>
<Login />
<View>
{
this.state.names.map((item, index) => (
<TouchableOpacity
key = {item.id}
style = {styles.listCont}
onPress = {() => console.log('hello')}>
<Text style = {styles.text}>
{item.name}
</Text>
</TouchableOpacity>
))
}
</View>
<View style={{marginRight: 50}}>
<Text style={{marginTop: 40, textAlign:"right",fontWeight: "bold"}}>STAY IN TOUCH</Text>
<TextInput style={{textAlign:"right", marginTop: 10, borderColor: 'black'}}placeholder="Sign up for GOLDENSHOE news" type="text" />
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
marginLeft: 10
},
header: {
fontWeight: 'bold',
marginTop: 40,
marginBottom: 30,
color: "lightgreen",
fontSize: 30,
},
button: {
alignItems: 'flex-start',
marginTop: 30,
flexDirection: 'column',
borderBottomColor: "black",
borderBottomWidth: 1,
borderTopColor: "black",
borderTopWidth: 1,
},
listCont: {
padding: 10,
marginTop: 3,
borderBottomWidth: 1
},
login: {
borderRadius: 10
}
})
export default Profile;
I am new to react native this is my first attempt in react native I was following a sample tutorial for the basic understanding of the code and other things I am following this raywenderlich's propertyfinder example, while implementing the first navigation example I am facing this issue:
undefined is not a function (evaluating 'this.props.renderScene(route,this)')
in my android device(Samsung J7) which I am using to run the app
Here is my index.android.js
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var SearchPage = require('./SearchPage');
var styles = ReactNative.StyleSheet.create({
text: {
color: 'black',
backgroundColor: 'white',
fontSize: 30,
margin: 80
},
container: {
flex: 1
}
});
class PropertyFinderApp extends React.Component {
render() {
return (
<ReactNative.Navigator
style={styles.container}
renderScene={this.renderScene}
initialRoute={{
component: SearchPage,
index:0,
title:"home"
}}/>
);
}
}
ReactNative.AppRegistry.registerComponent('PropertyFinder', function() { return PropertyFinderApp });`
and the SearchPage.js file(the other component which I am using):
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
Text,
TextInput,
View,
TouchableHighlight,
ActivityIndicator,
Image
} from 'react-native';
var styles = StyleSheet.create({
description: {
marginBottom: 20,
fontSize: 18,
textAlign: 'center',
color: '#656565'
},
container: {
padding: 30,
marginTop: 65,
alignItems: 'center'
},
flowRight: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'stretch'
},
buttonText: {
fontSize: 18,
color: 'white',
alignSelf: 'center'
},
button: {
height: 36,
flex: 1,
flexDirection: 'row',
backgroundColor: '#48BBEC',
borderColor: '#48BBEC',
borderWidth: 1,
borderRadius: 8,
marginBottom: 10,
alignSelf: 'stretch',
justifyContent: 'center'
},
searchInput: {
height: 36,
padding: 4,
marginRight: 5,
flex: 4,
fontSize: 18,
borderWidth: 1,
borderColor: '#48BBEC',
borderRadius: 8,
color: '#48BBEC'
}
});
export default class SearchPage extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.description}>
Search for houses to buy!
</Text>
<Text style={styles.description}>
Search by place-name, postcode or search near your location.
</Text>
<View style={styles.flowRight}>
<TextInput
style={styles.searchInput}
placeholder='Search via name or postcode'/>
<TouchableHighlight style={styles.button}
underlayColor='#99d9f4'>
<Text style={styles.buttonText}>Go</Text>
</TouchableHighlight>
</View>
<TouchableHighlight style={styles.button}
underlayColor='#99d9f4'>
<Text style={styles.buttonText}>Location</Text>
</TouchableHighlight>
</View>
);
}
}
module.exports = SearchPage;
I have no idea what I am doing wrong since I am a beginner in this any help will be appreciated, thanx in advance.
You for got to write renderScene function, see following example:
<ReactNative.Navigator
...
renderScene={this.renderScene.bind(this)} />
renderScene(route, navigationOperations, onComponentRef) {
switch(route.index) {
case 0:
return <SearchPage />
}
}
I have react-native 0.30 installed and I have troubles to update and execute an old piece of code i found on internet.
Here is the old rn code :
"use strict";
var React = require("react-native");
var {
AppRegistry,
StyleSheet,
Text,
View,
TextInput,
AsyncStorage,
} = React;
var ReactProject = React.createClass({
componentDidMount: function() {
AsyncStorage.getItem("myKey").then((value) => {
this.setState({"myKey": value});
}).done();
},
getInitialState: function() {
return { };
},
render: function() {
return (
<View style={styles.container}>
<Text style={styles.saved}>
{this.state.myKey}
</Text>
<View>
<TextInput
style={styles.formInput}
onChangeText={(text) => this.saveData(text)}
value="" />
</View>
<Text style={styles.instructions}>
Type something into the text box. It will be saved to
device storage. Next time you open the application, the saved data
will still exist.
</Text>
</View>
);
},
saveData: function(value) {
AsyncStorage.setItem("myKey", value);
this.setState({"myKey": value});
}
});
var styles = StyleSheet.create({
container: {
padding: 30,
flex: 1,
justifyContent: "center",
alignItems: "stretch",
backgroundColor: "#F5FCFF",
},
formInput: {
flex: 1,
height: 26,
fontSize: 13,
borderWidth: 1,
borderColor: "#555555",
},
saved: {
fontSize: 20,
textAlign: "center",
margin: 10,
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5,
marginTop: 5,
},
});
AppRegistry.registerComponent('ReactProject', () => ReactProject);
And here is what I've done to update it :
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
"use strict";
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
TextInput,
AsyncStorage,
View
} from 'react-native';
class pulps extends Component {
componentDidMount() {
AsyncStorage.getItem("myKey").then((value) => {
this.setState({"myKey": value});
}).done();
}
getInitialState() {
return { };
}
render() {
return (
<View style={styles.container}>
<Text style={styles.saved}>
{this.state.myKey}
</Text>
<View>
<TextInput
style={styles.formInput}
onChangeText={(text) => this.saveData(text)}
value="" />
</View>
<Text style={styles.instructions}>
Type something into the text box. It will be saved to
device storage. Next time you open the application, the saved data
will still exist.
</Text>
</View>
);
}
saveData(value) {
return (
AsyncStorage.setItem("myKey", value);
this.setState({"myKey": value});
);
}
}
var styles = StyleSheet.create({
container: {
padding: 30,
flex: 1,
justifyContent: "center",
alignItems: "stretch",
backgroundColor: "#F5FCFF",
},
formInput: {
flex: 1,
height: 26,
fontSize: 13,
borderWidth: 1,
borderColor: "#555555",
},
saved: {
fontSize: 20,
textAlign: "center",
margin: 10,
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5,
marginTop: 5,
},
});
AppRegistry.registerComponent('pulps', () => pulps);
But I have the following error on the screen of my ios-simulator when I press cmd+R :
SyntaxError /Users/***/Documents/pulps/index.ios.js: Unexpected token(53:44)
Could you pls tell me where I am wrong ?
By the way is it better for that kind of script to use plain Javascript or ES6 ?
Thank you !
You've just an error in the method saveData when using "return" in a way that isn't allowed.
Your code:
saveData(value) {
return (
AsyncStorage.setItem("myKey", value);
this.setState({"myKey": value});
);
}
You can't use "return" here when calling two void methods. Just change it like this:
saveData(value) {
AsyncStorage.setItem("myKey", value);
this.setState({"myKey": value});
}