How Can I Reduce Codes In React Native? - reactjs

What I'm Trying To Do
My current code is like this.
import React from 'react';
import {
Container, Header, Body, View, Content, Title, Text, Left, Right
} from 'native-base';
import 'react-native-gesture-handler';
import Fire from 'app/src/Fire';
import {
StyleSheet, Image, TouchableOpacity,
} from 'react-native';
export default class All extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
};
}
async componentDidMount() {
const querySnapshot = await Fire.shared.getItems(1);
const items = await Fire.shared.pushItems(querySnapshot);
this.setState({ items });
}
render() {
const { items } = this.state;
return (
<Container>
<View>
{items.map((item) => (
<Image
source={{ uri: item.first_img_url }}
/>
<View>
<Text>{item.name}</Text>
</View>
))}
</View>
</Container>
);
}
}
I have another component that has almost same code as above one.
The differences are class name and
await Fire.shared.getItems(1);
or
await Fire.shared.getItems(2);
I know I should combine the same code into one component.
I would appreciate it if you could give me any advices or tips :)

You can extract this code and pass the number 1 or 2 in props.
import React from 'react';
import {
Container, Header, Body, View, Content, Title, Text, Left, Right
} from 'native-base';
import 'react-native-gesture-handler';
import Fire from 'app/src/Fire';
import {
StyleSheet, Image, TouchableOpacity,
} from 'react-native';
export default class All extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
};
}
async componentDidMount() {
const querySnapshot = await Fire.shared.getItems(this.props.nbrOfItems);
const items = await Fire.shared.pushItems(querySnapshot);
this.setState({ items });
}
render() {
const { items } = this.state;
return (
<Container>
<View>
{items.map((item) => (
<Image
source={{ uri: item.first_img_url }}
/>
<View>
<Text>{item.name}</Text>
</View>
))}
</View>
</Container>
);
}
}
You can call this component in any component like this
<All nbrOfItems={1} />
Or
<All nbrOfItems={2} />

Related

Navigating to other screen in combination with redux

I have the following to Component:
RestaurantTemplate :
import React from 'react';
import { StatusBar } from 'expo-status-bar';
import { ImageBackground, StyleSheet, View,TouchableOpacity} from 'react-native';
import { RestaurantData } from '../../Data';
import { connect } from 'react-redux';
import Restaurant from './Restaurant';
class RestaurantOverviewTemplate extends React.Component{
render() {
return(
<View style={{ flex: 1, justifyContent: 'center' }}>
<Restaurant restaurants={RestaurantData} onPress={this.props.changeToRestaurantId}/>
</View>
)
}
}
const mapDispatchToProps = (dispatch) => {
return {
changeToRestaurantId: (restaurants) => dispatch({ type: 'UPDATE_ID', payload: restaurants })
}
}
export default connect(null, mapDispatchToProps)(RestaurantOverviewTemplate);
Restaurant.js :
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
export default class Restaurant extends React.Component {
renderRestaurant = (restaurants) =>{
return restaurants.map((item, index) => {
return(
<View key={ index }>
<Button onPress={ () => this.props.onPress(item.id) } title={ item.name }/>
</View>
)
});
}
render() {
return (
<View>
{this.renderRestaurant(this.props.restaurants)}
</View>
)
}
}
So I have the RestaurantTemplate in which the Restaurant.js component is imported. What was my intension is to extract the id of a restaurant and pass it to the mapDispatchToProps function that updates a global variable. But my problem is that I want to navigate to another screen when one restaurant is pressed. I thought I could do this like so:
<Restaurant
restaurants={RestaurantData}
onPress={[this.props.changeToRestaurantId, () => this.props.navigation.navigate('RestaurantDetails']}
/>
But this won't work. I also can't wrap a TouchableOpacity around the <Restaurant../>.
Has anybody an idea how I could fix this?
Thanks in advance!!
It looks as though you want to invoke more than one function in the callback. You can wrap both calls in an anonymous function. Proxy the passed restaurant id to changeToRestaurantId and invoke the navigation. This, of course, assumes you have correctly injected navigation as a prop into RestaurantOverviewTemplate component.
<Restaurant
restaurants={RestaurantData}
onPress={(id) => {
this.props.changeToRestaurantId(id);
this.props.navigation.navigate('RestaurantDetails');
}}
/>

Send value to function in React-Native

I am trying to send value of TextInput to another Class Function in console.log. My approach is when the button is pressed the value FromStr in TextInput will got passed into another class function. Here's my code
import React, { Component } from "react";
import { StyleSheet, Text, View, TextInput, Button } from "react-native";
import receiveMessage from "./receiveMessage"
export default class WeatherProject extends Component{
constructor (props) {
super(props);
this.state={
From:'',
FromStr:'',
}
}
changeText=(From)=>{
this.setState({From})
}
changeText1=(To)=>{
this.setState({To})
}
onPress = ()=>{
this.setState({FromStr: this.state.From})
receiveMessage.receiveMessage();
}
render(){
return (
<View>
<View style={styles.inputFields}>
<TextInput placeholder="From" id="from" style={styles.fromField} onChangeText={this.changeText} />
<View style={styles.buttonStyle}>
<Button
title={"Go Back"}
color="#f194ff"
onPress={this.onPress}
></Button>
</View>
</View>
</View>
);
}
}
receiveMessage.js
import React, { Component } from "react";
export default class receiveMessage extends Component {
static receiveMessage=()=>{
console.log(this.state.FromStr)
}
}
React does not allow to pass the data between react components in this way.
Following is way to pass the data between components in React. To get more insights please follow
import React, { Component } from 'react';
class WeatherProject extends Component {
render() {
const messageToPassed = 'Hello';
return (
<div>
<ReceiveMessage message={messageToPassed} />
</div>
);
}
}
const ReceiveMessage = props => <h1>{props.message}</h1>;
export default App;
here we pass the value from sidemenu component by raising an event
App.js
class App extends React.Component {
handleSubmit = (e, data) => console.log(`my data from props`, data);
render() {
return (
<Sidemenu
onSubmit={(e, data)=>this.handleSubmit(e, data)} />
);
}
}
SideMenu.js
const Sidemenu = props => {
const { onSubmit} = props;
return (
<button onClick={(e, type)=>this.onSubmit(e, 'mydata')} />
);
}

Props variable is not found

I'm learning react native using expo-cli. I'm working on a little exercise to display information about movies after fetching them from API using axios http client. But when I try to pass data from a parent component MoviesList to a child component MovieDetails I get the following screen:
Here is my App component code :
import { View } from 'react-native';
import React, { Component } from 'react';
import Header from './src/components/Header';
import MoviesList from './src/components/MoviesList';
import axios from 'axios';
const API_KEY = "mykey";
class App extends Component {
constructor(props) {
super(props);
this.state = {
movies:[],
movieToSearch:"avengers"
};
}
componentDidMount=async()=>{
const res = await axios.get(`http://www.omdbapi.com/?s=${this.state.movieToSearch}&apikey=${API_KEY}`);
// const data=await res.json();
this.setState({ movies:res.data.Search });
}
render() {
return (
<View style={ { flex:1 } }>
<Header title={"Films"} />
<MoviesList movies={ this.state.movies } />
</View>
);
}
}
export default App;
Code for MoviesList.js:
import React,{ Component } from 'react';
import { View } from 'react-native';
import MovieDetails from './MovieDetails';
class MoviesList extends Component{
renderMovies(){
const { movies } = this.props;
if(movies){
return movies.map(movie => {
return <MovieDetails key={ movie.imdbID } movie = { movie } />
});
}else{
return;
}
}
render(){
return (
<View>
{ this.renderMovies() }
</View>
)
}
}
export default MoviesList;
Code for MovieDetails.js:
import React from 'react';
import { View, Text } from 'react-native';
import Card from './Card';
import CardSection from './CardSection';
import Button from './Button';
const MovieDetails = () =>{
const { Title, Year, Poster } = props.movie;
return (
<Card>
<CardSection>
<Text>{ Title }</Text>
</CardSection>
<CardSection>
<Text>{ Title }</Text>
</CardSection>
<CardSection>
<Button btnLabel="Voir les details" />
</CardSection>
</Card>
)
}
export default MovieDetails;
Everything seems good in my code, and I don't know where the error is coming from.
Here is the github repo so that you can test it locally :https://github.com/jochri3/movieslist
convert
const { Title, Year, Poster } = props.movie;
return (
<Card>
<CardSection>
<Text>{ Title }</Text>
</CardSection>
<CardSection>
<Text>{ Title }</Text>
</CardSection>
<CardSection>
<Button btnLabel="Voir les details" />
</CardSection>
</Card>
)
}
to
const MovieDetails = ({movie}) => ({
<Card>
<CardSection>
<Text>{ movie.Title }</Text>
</CardSection>
...
</Card>
})
and
class MoviesList extends Component{
renderMovies(){
const { movies } = this.props;
if(movies){
return movies.map(movie => {
return <MovieDetails key={ movie.imdbID } movie = { movie } />
});
}else{
return;
}
}
render(){
return (
<View>
{ this.renderMovies() }
</View>
)
}
}
with
class MoviesList extends Component{
constructor(props){
super(props)
}
renderMovies = () => {
const { movies } = this.props;
return movies.map(movie => {
return <MovieDetails key={ movie.imdbID } movie = { movie } />
});
}
render(){
return (
<View>
{ this.renderMovies() }
</View>
)
}
}
Functional components pass props as an argument.
const MovieDetails = () =>{
const { Title, Year, Poster } = props.movie;
return (
<Card>
...
To this:
const MovieDetails = (props) =>{
const { Title, Year, Poster } = props.movie;
return (
<Card>
...
You are using functional component for MovieDetails as follow:
const MovieDetails = () => {
const { Title, Year, Poster } = props.movie;
.......
}
But actual implementation for it is as follow:
const MovieDetails = (props) => {
const { Title, Year, Poster } = props.movie;
......
}
I hope it help you.
const MovieDetails = () =>{
has to be
const MovieDetails = props => {
The component is a function and props are its argument.

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>
);
}

Scroll-View React-Native Not functioning

Parent Component
const App = () => (
<View style={{ flex: 1 }}>
<Header headerText={'Albums'} />
<AlbumList />
</View>
);
Scroll View
import React, { Component } from 'react';
import { ScrollView } from 'react-native';
import axios from 'axios';
import AlbumDetail from './AlbumDetail';
class AlbumList extends Component {
state={ albums: [] };
componentWillMount() {
axios.get('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => this.setState({ albums: response.data }));
}
renderAlbums() {
return this.state.albums.map(album =>
<AlbumDetail key={album.title} album={album} />);
}
render() {
console.log(this.state);
return (
<ScrollView >
{this.renderAlbums()}
</ScrollView>
);
}
}
export default AlbumList;
I am trying to make a ScrollView work. These are the snippet. But still when I run the simulator the scroll view is not working and not giving the full lists of the items.
Try this, basically change the render method return
import React, { Component } from 'react';
import { ScrollView } from 'react-native';
import axios from 'axios';
import AlbumDetail from './AlbumDetail';
class AlbumList extends Component {
this.state={ albums: [] };
componentDidMount() {
axios.get('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => this.setState({ albums: response.data }));
}
renderAlbums() {
return this.state.albums.map(album =>
<AlbumDetail key={album.title} album={album} />);
}
render() {
console.log(this.state);
return (
<div>
<ScrollView></ScrollView>
{this.renderAlbums()}
</div>
);
}
}
export default AlbumList;

Resources