I am using the react-native-autocomplete-input package for auto-complete searching.
https://www.npmjs.com/package/react-native-autocomplete-input
Here is a template code which works:
//Example of React Native AutoComplete Input
//https://aboutreact.com/example-of-react-native-autocomplete-input/
//import React in our code
import React, {useState, useEffect} from 'react';
//import all the components we are going to use
import {
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
//import Autocomplete component
import Autocomplete from 'react-native-autocomplete-input';
const App = () => {
const [films, setFilms] = useState([]); // For the main data
const [filteredFilms, setFilteredFilms] = useState([]); // Filtered data
const [selectedValue, setSelectedValue] = useState({}); // selected data
useEffect(() => {
fetch('https://aboutreact.herokuapp.com/getpost.php?offset=1')
.then((res) => res.json())
.then((json) => {
const {results: films} = json;
setFilms(films);
//setting the data in the films state
})
.catch((e) => {
alert(e);
});
}, []);
const findFilm = (query) => {
//method called everytime when we change the value of the input
if (query) {
//making a case insensitive regular expression
const regex = new RegExp(`${query.trim()}`, 'i');
//setting the filtered film array according the query
setFilteredFilms(
films.filter((film) => film.title.search(regex) >= 0)
);
} else {
//if the query is null then return blank
setFilteredFilms([]);
}
};
return (
<SafeAreaView style={{flex: 1}}>
<View style={styles.container}>
<Autocomplete
autoCapitalize="none"
autoCorrect={false}
containerStyle={styles.autocompleteContainer}
//data to show in suggestion
data={filteredFilms}
//default value if you want to set something in input
defaultValue={
JSON.stringify(selectedValue) === '{}' ?
'' :
selectedValue.title
}
// onchange of the text changing the state of the query
// which will trigger the findFilm method
// to show the suggestions
onChangeText={(text) => findFilm(text)}
placeholder="Enter the film title"
renderItem={({item}) => (
//you can change the view you want to show in suggestions
<TouchableOpacity
onPress={() => {
setSelectedValue(item);
setFilteredFilms([]);
}}>
<Text style={styles.itemText}>
{item.title}
</Text>
</TouchableOpacity>
)}
/>
<View style={styles.descriptionContainer}>
{films.length > 0 ? (
<>
<Text style={styles.infoText}>
Selected Data
</Text>
<Text style={styles.infoText}>
{JSON.stringify(selectedValue)}
</Text>
</>
) : (
<Text style={styles.infoText}>
Enter The Film Title
</Text>
)}
</View>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#F5FCFF',
flex: 1,
padding: 16,
marginTop: 40,
},
autocompleteContainer: {
backgroundColor: '#ffffff',
borderWidth: 0,
},
descriptionContainer: {
flex: 1,
justifyContent: 'center',
},
itemText: {
fontSize: 15,
paddingTop: 5,
paddingBottom: 5,
margin: 2,
},
infoText: {
textAlign: 'center',
fontSize: 16,
},
});
export default App;
The input box looks like below.
I want a search icon at the right/left inside of the search input box.
Is there any way I can do this?
Here is the working code with
//Example of React Native AutoComplete Input
//https://aboutreact.com/example-of-react-native-autocomplete-input/
//import React in our code
import React, {useState, useEffect} from 'react';
import AntDesign from 'react-native-vector-icons/AntDesign';
//import all the components we are going to use
import {
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
//import Autocomplete component
import Autocomplete from 'react-native-autocomplete-input';
const App = () => {
const [films, setFilms] = useState([]); // For the main data
const [filteredFilms, setFilteredFilms] = useState([]); // Filtered data
const [selectedValue, setSelectedValue] = useState({}); // selected data
useEffect(() => {
fetch('https://aboutreact.herokuapp.com/getpost.php?offset=1')
.then((res) => res.json())
.then((json) => {
const {results: films} = json;
setFilms(films);
//setting the data in the films state
})
.catch((e) => {
alert(e);
});
}, []);
const findFilm = (query) => {
//method called everytime when we change the value of the input
if (query) {
//making a case insensitive regular expression
const regex = new RegExp(`${query.trim()}`, 'i');
//setting the filtered film array according the query
setFilteredFilms(
films.filter((film) => film.title.search(regex) >= 0)
);
} else {
//if the query is null then return blank
setFilteredFilms([]);
}
};
return (
<View style={{flex: 1}}><View><Text>Hello Friend</Text></View>
<View style={styles.container}>
<View style={styles.searchSection}>
<AntDesign
name="search1"
size={18}
color="gray"
style={styles.searchIcon}
/>
<Autocomplete
autoCapitalize="none"
autoCorrect={false}
containerStyle={styles.autocompleteContainer}
inputContainerStyle={styles.inputContainer}
//data to show in suggestion
data={filteredFilms}
//default value if you want to set something in input
defaultValue={
JSON.stringify(selectedValue) === '{}'
? ''
: selectedValue.title + selectedValue.id
}
// onchange of the text changing the state of the query
// which will trigger the findFilm method
// to show the suggestions
onChangeText={(text) => findFilm(text)}
placeholder="Search doctors, specialities, symptoms"
renderItem={({item}) => (
//you can change the view you want to show in suggestions
<View>
<TouchableOpacity
onPress={() => {
setSelectedValue(item);
setFilteredFilms([]);
}}>
<Text style={styles.itemText}>{item.title + item.id}</Text>
</TouchableOpacity>
</View>
)}
/>
<AntDesign
name="close"
size={18}
color="gray"
style={styles.clearIcon}
/>
</View>
<View style={styles.descriptionContainer}>
{films.length > 0 ? (
<>
<Text style={styles.infoText}>
Selected Data
</Text>
<Text style={styles.infoText}>
{JSON.stringify(selectedValue)}
</Text>
</>
) : (
<Text style={styles.infoText}>
Enter The Film Title
</Text>
)}
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#F5FCFF',
flex: 1,
padding: 16,
marginTop: 40,
},
autocompleteContainer: {
backgroundColor: '#ffffff',
borderWidth: 0,
marginLeft: 10,
marginRight: 10,
//paddingLeft: 15,
},
inputContainer: {
//minWidth: 300,
//width: "90%",
//height: 55,
backgroundColor: 'transparent',
//color: '#6C6363',
//fontSize: 18,
//fontFamily: 'Roboto',
borderBottomWidth: 1,
//borderBottomColor: 'rgba(108, 99, 99, .7)',
borderColor: 'transparent',
},
descriptionContainer: {
flex: 1,
justifyContent: 'center',
},
itemText: {
fontSize: 15,
paddingTop: 5,
paddingBottom: 5,
margin: 2,
},
infoText: {
textAlign: 'center',
fontSize: 16,
},
// testing below
searchSection: {
flex: 1,
height: 50,
borderRadius: 10,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginLeft: '5%',
marginRight: '5%',
backgroundColor: '#fff',
},
searchIcon: {
//padding: 10,
paddingLeft: 10,
backgroundColor: 'transparent',
},
clearIcon: {
paddingRight: 10,
backgroundColor: 'transparent',
},
});
export default App;
npm install react-native-vector-icons for the AntDesign icons.
I am using "react-native-vector-icons": "^7.1.0".
Your output will be like:
Have a great day!!
Related
I am developing a PDF viewer app.
Problem: I am displaying all the PDF's using Flatlist that is stored in a Firebase database. I am using react-native expo. When I open the application in a browser with expo it works. But when I run it on my phone it shows me an error as given below.
Error: Render Error : Text strings must be rendered within a <Text> Component
import React,{useEffect, useState} from "react";
import { FlatList, Text, StyleSheet, TouchableOpacity, View} from
"react-native";
import { config } from "../firebaseconfig";
import { getDatabase, ref ,onValue } from "firebase/database";
import { initializeApp } from "firebase/app";
const app = initializeApp(config);
function Books({navigation}) {
const [value ,setValue] = useState([]);
function readFunction() {
const db = getDatabase(app);
const reference = ref(db, "Books");
onValue(reference, (snapshot) => {
var main = [];
snapshot.forEach((childSnapshot) => {
const childKey = childSnapshot.key;
const childData = childSnapshot.val();
main.push({
title: childKey,
key:childData
});
});
setValue(main);
})
}
useEffect(() => {
readFunction()
},[]);
function renderItem({item}){
const path = item.key;
return (
<View style={styles.container}>
<View style={styles.square}>
<Text style={styles.h1}>{item.title}</Text>
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate('Document', {path})}>Read</TouchableOpacity>
</View>
</View>
)
};
return (
<FlatList
data={value}
renderItem={renderItem}
keyExtractor={item => item.key}
/>
)
}
const styles = StyleSheet.create({
container:{
display: 'flex',
paddingLeft: '30px',
paddingRight:'30px',
paddingTop:'20px',
paddingBottom:'10px'
},
square:{
backgroundColor: 'white',
borderRadius: 4,
padding: '30px',
shadowColor: 'black',
shadowRadius: 10,
shadowOpacity: 1,
},
h1:{
textAlign: 'left',
fontFamily: 'Merriweather',
fontSize: 30,
},
p: {
textAlign: 'justify',
fontFamily: 'Open Sans',
fontSize: 15,
color: '#C8C8C8',
lineHeight: 18,
},
button: {
backgroundColor: '#3EDD84',
color: 'white',
width: '90px',
borderRadius: 3,
textAlign: 'center',
display: 'flex',
marginTop: '15px',
marginRight: '70px',
lineHeight:30,
fontSize: 25,
fontFamily: 'merriweather',
}
});
export default Books;
Try Doing this same
<View style={styles.container}>
<View style={styles.square}>
<Text style={styles.h1}>{item.title}</Text>
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate('Document', {path})}>
<Text>Read</Text>
</TouchableOpacity>
</View>
You can't add Text inside TouchableOpacity component
Do this:
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate('Document', {path})}>
<Text>Read</Text>
</TouchableOpacity>
I think the word Read between the TouchableOpacity tags should be within Text tags.
When I click the RoundedButton the TouchableOpacity works i.e the opacity of the button reduces but the onPress function doesn't work, the data being passed to the onPress function is correct(as given in the code below). Also, when I tried to console.log("something") inside the onPress function, it doesn't get printed in the console of my terminal.
Here I have the code with function component.
Focus.js file
import React, { useState } from "react";
import { Text, View, StyleSheet } from "react-native";
import { TextInput } from "react-native-paper";
import { RoundedButton } from "../../component/RoundedButton";
export const Focus = ({ addSubject }) => {
const [tmpItem, setTmpItem] = useState();
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>What would you like to focus on?</Text>
<View style={styles.inputContainer}>
<TextInput
style={{ flex: 1, marginRight: 20 }}
onSubmitEditing={({ nativeEvent }) => {
setTmpItem(nativeEvent.text);
console.log("tmpItem value set " + tmpItem);
}}
/>
<RoundedButton
size={50}
title="+"
onPress={() => {
console.log("value passed!");
addSubject(tmpItem);
}}
/>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
titleContainer: {
flex: 0.5,
padding: 10,
justifyContent: "center",
},
title: {
color: "white",
fontWeight: "bold",
fontSize: 21,
},
inputContainer: {
paddingTop: 10,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
},
});
RoundedButton.js File
import React from "react";
import { TouchableOpacity, Text, StyleSheet } from "react-native";
export const RoundedButton = ({
style = {},
textStyle = {},
size = 125,
...props
}) => {
return (
<TouchableOpacity style={[styles(size).radius, style]}>
<Text style={[styles.text, textStyle]}>{props.title}</Text>
</TouchableOpacity>
);
};
const styles = (size) =>
StyleSheet.create({
radius: {
borderRadius: size / 2,
width: size,
height: size,
alignItems: "center",
justifyContent: "center",
borderColor: "white",
borderWidth: 2,
},
text: {
color: "white",
fontSize: size / 3,
},
});
App.js file
import React, { useState } from "react";
import { Text, View, StyleSheet } from "react-native";
import { Focus } from "./src/features/focus/Focus";
export default function App() {
const [focusSubject, setFocusSubject] = useState(null);
return (
<View style={styles.container}>
{focusSubject ? (
<Text style={{ flex: 1, color: "white", fontSize: 30 }}>
Here is where I am going to build a timer
</Text>
) : (
<Focus addSubject={setFocusSubject} />
)}
<Text style={{ flex: 1, color: "white", fontSize: 30 }}>
{focusSubject}
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 50,
backgroundColor: "#252250",
},
});
you need to extract your onPress props in RoundButton.js and pass to your TouchableOpacity
export const RoundedButton = ({
style = {},
textStyle = {},
size = 125,
onPress,//<===this
...props
}) => {
return (
<TouchableOpacity onPress={onPress} style={[styles(size).radius, style]}>
<Text style={[styles.text, textStyle]}>{props.title}</Text>
</TouchableOpacity>
);
};
it's seem that you forget to pass onPress function to TouchOpacity
export const RoundedButton = ({
style = {},
textStyle = {},
size = 125,
onPress,
...props
}) => {
return (
<TouchableOpacity onPress={onPress} style={[styles(size).radius, style]}>
<Text style={[styles.text, textStyle]}>{props.title}</Text>
</TouchableOpacity>
);
};
Now It's Working
Focus.js file
import React, { useState } from "react";
import { Text, View, StyleSheet } from "react-native";
import { TextInput } from "react-native-paper";
import { RoundedButton } from "../../component/RoundedButton";
export const Focus = ({ addSubject }) => {
const [tmpItem, setTmpItem] = useState();
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>What would you like to focus on?</Text>
<View style={styles.inputContainer}>
<TextInput
style={{ flex: 1, marginRight: 20 }}
onSubmitEditing={({ nativeEvent }) => {
setTmpItem(nativeEvent.text);
console.log("tmpItem value set " + tmpItem);
}}
/>
<RoundedButton
size={50}
title="+"
onPress={() => {
console.log("value passed!");
addSubject(tmpItem);
}}
/>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
titleContainer: {
flex: 0.5,
padding: 10,
justifyContent: "center",
},
title: {
color: "white",
fontWeight: "bold",
fontSize: 21,
},
inputContainer: {
paddingTop: 10,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
},
});
RoundedButton.js File
import React from "react";
import { TouchableOpacity, Text, StyleSheet } from "react-native";
export const RoundedButton = ({
style = {},
textStyle = {},
size = 125,
onPress,
...props
}) => {
return (
<TouchableOpacity onPress={onPress} style={[styles(size).radius, style]}>
<Text style={[styles.text, textStyle]}>{props.title}</Text>
</TouchableOpacity>
);
};
const styles = (size) =>
StyleSheet.create({
radius: {
borderRadius: size / 2,
width: size,
height: size,
alignItems: "center",
justifyContent: "center",
borderColor: "white",
borderWidth: 2,
},
text: {
color: "white",
fontSize: size / 3,
},
});
App.js file
import React, { useState } from "react";
import { Text, View, StyleSheet } from "react-native";
import { Focus } from "./src/features/focus/Focus";
export default function App() {
const [focusSubject, setFocusSubject] = useState();
return (
<View style={styles.container}>
{focusSubject ? (
<Text style={{ flex: 1, color: "white", fontSize: 30 }}>
Here is where I am going to build a timer
</Text>
) : (
<Focus addSubject={setFocusSubject} />
)}
<Text style={{ flex: 1, color: "white", fontSize: 30 }}>
{focusSubject}
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 50,
backgroundColor: "#252250",
},
});
We created a FlatList component and a Contact screen in our app. We want to add 'heart' icon to the near of the images in Contact screen. We added heart icon near to all of items. But, if we pressed one of these icons, it changes all of theirs colors to red, not only one of them. We want to change the color of clicked item.
Screenshot of our program:
This is our FlatList component:
import React, { Component } from 'react';
import { View, Text, SafeAreaView, StyleSheet, FlatList, Image, TouchableOpacity,
TouchableWithoutFeedback, TextInput } from 'react-native';
import { Right, Icon } from 'native-base';
import data from '../../data';
export default class FlatListComponent extends Component {
state = {
text: '',
contacts: data,
like: false,
color: 'white',
}
toggleLike=()=>{
this.setState({
like: !this.state.like
})
if(this.state.like){
this.setState({
color: 'red',
})
}else{
this.setState({
color: 'white',
})
}
}
renderContactsItem = ({item, index}) => {
return (
<View style={[styles.itemContainer]}>
<Image
style={styles.avatar}
source={{ uri: item.image }} />
<View style={styles.textContainer}>
<Text style={[styles.name], {color: '#fafafa'}}>{item.first_name}</Text>
<Text style={{ color: '#fafafa' }}>{item.last_name}</Text>
</View>
<Right style={{justifyContent: 'center'}}>
<TouchableWithoutFeedback onPress={this.toggleLike}>
{/*{this.like ? (
<Icon name="heart" type='FontAwesome' style={{paddingRight: 10, fontSize: 30, color: 'red'}} />
) :
( <Icon name="heart" type='FontAwesome' style={{paddingRight: 10, fontSize: 30, color: 'white'}} /> )
}*/}
<Icon name='heart' type='FontAwesome' size={32} style={{color: this.state.color === "white" ? 'white' :'red', paddingRight: 10 }}/>
{/*<Icon name="heart" type='FontAwesome' style={{paddingRight: 10, fontSize: 30, color: this.state.color}} />*/}
</TouchableWithoutFeedback>
</Right>
</View>
);
}
searchFilter = text => {
const newData = data.filter(item => {
const listItems = `${item.first_name.toLowerCase()}`
return listItems.indexOf(text.toLowerCase()) > -1;
});
this.setState({
contacts: newData,
});
};
renderHeader = () => {
const {text} = this.state;
return (
<View style={styles.searchContainer}>
<TextInput
onChangeText = {text => {
this.setState ({
text,
});
this.searchFilter(text);
}}
value={text}
placeholder="Search..."
style={styles.searchInput} />
</View>
)
}
render() {
return (
<FlatList
ListHeaderComponent={this.renderHeader()}
renderItem={this.renderContactsItem}
keyExtractor={item => item.id}
data={this.state.contacts}
/>
);
}
}
const styles = StyleSheet.create({
itemContainer: {
flex: 1,
flexDirection: 'row',
paddingVertical: 10,
borderBottomWidth: 1,
borderBottomColor: '#eee'
},
avatar: {
width: 50,
height: 50,
borderRadius: 25,
marginHorizontal: 10,
},
textContainer: {
justifyContent: 'space-around',
},
name: {
fontSize: 16,
},
searchContainer: {
padding: 10
},
searchInput: {
fontSize: 16,
backgroundColor: '#f9f9f9',
padding: 10,
}
});
Our Contact screen is just:
import React from 'react';
import 'SafeAreaView' from 'react-native';
import FlatList from './FlatList';
export default function Contact() {
<SafeAreaView style={{ flex: 1 }}>
<FlatList />
</SafeAreaView>
}
How can we implement this?
I've run into this recently :) One option is to make the renderContactsItem its own component. For example:
const RenderContactsItem = ({item, index}) => {
const [like, setLike] = useState(false);
const [color, setColor] = useState("white");
const toggleLike = () => {
setLike(!like)
if(like) {
setColor("red");
} else {
setColor("white");
}
}
return (
<View style={[styles.itemContainer]}>
<Image
style={styles.avatar}
source={{ uri: item.image }} />
<View style={styles.textContainer}>
<Text style={[styles.name], {color: '#fafafa'}}>{item.first_name}</Text>
<Text style={{ color: '#fafafa' }}>{item.last_name}</Text>
</View>
<Right style={{justifyContent: 'center'}}>
<TouchableWithoutFeedback onPress={toggleLike}>
<Icon name='heart' type='FontAwesome' size={32} style={{color, paddingRight: 10 }}/>
</TouchableWithoutFeedback>
</Right>
</View>
);
}
In this case, each item manages its own state, so setting like doesn't set it for every item.
Another option would be to build an object with "like" states and set the values as the hearts are pressed. For example:
state = {
text: '',
contacts: data,
like: {},
color: 'white', // You don't need this
}
Then, when a heart is pressed, you can send toggleLike the index, and set the state like so:
toggleLike = (index) => {
let newLike = {...this.state.like};
newLike[index] = !Boolean(newLike[index]);
this.setState({
like: newLike,
});
}
And render the color conditionally depending on the index value of the like state, like so:
<Icon name='heart' type='FontAwesome' size={32} style={{color: this.state.like[index] ? 'red' :'white', paddingRight: 10 }}/>
I'm new here and in react-native.
I want render some data from IMDB Api with the "hook" method.
So I try to render data in a flatlist, I can see in the console that the data is retrieved properly in a jSon format witch is a good thing but when I open my app I don't see any rendering on the screen.
I try to use the 'Hook' method and not the 'classes' and I'm pretty sure that I don't use properly the useState method.
So any help or advices are welcome.
My code:
App
import React, { useState } from "react";
import {
View,
Text,
StyleSheet,
Button,
TextInput,
FlatList,
} from "react-native";
// import films from "../Helpers/filmsData";
import FilmsItem from "./FilmsItem";
import getFilmsFromApiWithSearchedText from "../Api/TMDBApi";
const Search = () => {
const [films, setFilms] = useState([]);
const _loadFilms = () => {
getFilmsFromApiWithSearchedText("White").then(
(data) => setFilms({ film: data.results }),
console.log(films)
);
};
return (
<View style={styles.container}>
<TextInput style={styles.input} placeholder="Titre du film" />
<Button
style={styles.button}
title="Rechercher"
onPress={() => _loadFilms()}
/>
<FlatList
data={setFilms.films}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => <FilmsItem films={item} />}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
},
input: {
marginLeft: 5,
marginRight: 5,
height: 50,
paddingLeft: 5,
borderWidth: 1,
borderColor: "#000000",
},
});
export default Search;
Api request:
// Api/TMDBApi.js
const API_TOKEN = "**************************";
const getFilmsFromApiWithSearchedText = (text) => {
const url =
"https://api.themoviedb.org/3/search/movie?api_key=" +
API_TOKEN +
"&language=en&query=" +
text;
return fetch(url)
.then((response) => response.json())
.catch((error) => console.error(error));
};
export default getFilmsFromApiWithSearchedText;
FilmItem:
import React from "react";
import { View, Text, StyleSheet, Image } from "react-native";
const FilmsItem = (props) => {
const film = props.film;
return (
<View style={styles.container}>
<Image style={styles.img} source={{ uri: "image" }} />
<View style={styles.content}>
<View style={styles.header}>
<Text style={styles.title}>{film.title}</Text>
<Text style={styles.vote}>{film.vote_average}</Text>
</View>
<View style={styles.synopsis}>
<Text style={styles.synopsysText} numberOfLines={6}>
{film.overview}
</Text>
</View>
<View style={styles.date}>
<Text style={styles.dateText}>Sorti le {film.release_date}</Text>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: "row",
height: 190,
},
content: {
flex: 1,
margin: 5,
},
img: {
height: 180,
width: 120,
margin: 5,
backgroundColor: "gray",
},
header: {
flex: 3,
flexDirection: "row",
},
title: {
flex: 1,
flexWrap: "wrap",
fontWeight: "bold",
fontSize: 20,
paddingRight: 5,
},
vote: {
fontWeight: "bold",
fontSize: 20,
color: "#666666",
},
synopsis: {
flex: 7,
},
synopsysText: {
fontStyle: "italic",
color: "#666666",
},
date: {
flex: 1,
paddingBottom: 10,
},
dateText: {
textAlign: "right",
fontSize: 14,
},
});
export default FilmsItem;
const _loadFilms = () => {
getFilmsFromApiWithSearchedText("White").then(
(data) => setFilms({ film: data.results }),
console.log(films)
);
};
setFilms({ film: data.results }) will set an object, but you need an array in there.
Try to do something like this: setFilms(data.results)
use useState in this way
const _loadFilms = () => {
getFilmsFromApiWithSearchedText("White").then(
(data) => setFilms(data.results),
console.log(films)
);
};
then in Flatlist you can use like this
return (
<View style={styles.container}>
<TextInput style={styles.input} placeholder="Titre du film" />
<Button
style={styles.button}
title="Rechercher"
onPress={() => _loadFilms()}
/>
<FlatList
data={films}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => <FilmsItem films={item} />}
/>
</View>
);
I want to send basic data from Home.js component to details.js component.
My home.js
import React, { useState, useEffect } from 'react'
import { View, TouchableHighlight, Image, FlatList, ActivityIndicator, Text, StyleSheet } from 'react-native'
function HomeScreen({ navigation }) {
const [isLoading, setIsLoading] = useState(true)
const [dataSource, setDataSource] = useState([])
useEffect(() => {
fetch('http://www.json-generator.com/api/json/get/bVxGaxSSgi?indent=2')
.then((response) => response.json())
.then((responseJson) => {
setIsLoading(false)
setDataSource(responseJson)
})
.catch((error) => {
alert(error)
});
})
if (isLoading) {
return (
<View style={{ flex: 1, padding: 20 }}>
<ActivityIndicator />
</View>
)
}
return (
<View style={{ flex: 1, paddingTop: 20, paddingHorizontal: 20 }}>
<FlatList
data={dataSource}
renderItem={({ item }) =>
<TouchableHighlight onPress={() => navigation.navigate('Details',{text:'alperen'})} underlayColor="white">
<View style={styles.button}>
<View style={styles.div}>
<View style={styles.inlineDiv}>
<Image source={{ uri: 'https://source.unsplash.com/random/900�/?fruit' }} style={styles.pic} />
<Text>{item.name}, {item.about}</Text>
</View>
</View>
</View>
</TouchableHighlight>
}
keyExtractor={({ _id }, index) => _id}
/>
</View>
)
}
export default HomeScreen
const styles = StyleSheet.create({
pic: {
width: '100%',
height: 200,
borderRadius: 20,
},
div: {
shadowColor: "#fff",
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.20,
shadowRadius: 50,
elevation: 0,
marginBottom: 10
},
inlineDiv: {
padding: 5,
},
button: {
alignItems: 'center',
},
});
This is my details.js component
import React, { useEffect } from 'react'
import { View, Text } from 'react-native'
function DetailsScreen( navigation ) {
useEffect(() => {
alert(navigation.text)
})
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
export default DetailsScreen
I want to go to the other page and at the same time I want to send and print the data. This code is currently returning undefined. How Can I send data ? Probably I can use props but I don't know usage.
Change
function DetailsScreen( navigation ) {
useEffect(() => {
alert(navigation.text)
})
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
to
function DetailsScreen({navigation}) {
useEffect(() => {
alert(navigation.state.params.text)
})
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
And try
In first screen
<TouchableHighlight onPress={() => navigation.navigate('Details',{item})} underlayColor="white">
In next screen you can get data
this.props.navigation.state.params.item
Example:
<Image source={this.props.navigation.state.params.item.img}/>
<Text>{this.props.navigation.state.params.item.text}</Text>
Sending data operation is success but details page is not working. I looked 'react-navigation documentation ' (https://reactnavigation.org/docs/en/params.html). There is a keyword ('route') we have to use it.
function DetailsScreen({ route }) {
const { text } = route.params;
useEffect(() => {
var a = JSON.stringify(text)
alert(a)
})
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
I tried this code and its working success.