I have a problem, when I do a search, I get the data from my API, the first time I do a search, everything is fine, all the data is displayed. However, when I do a second search immediately, nothing is updated.
I put in console.log, and I see that I'm getting this data back, yet the display is not updated.
import React, { Component } from "react";
import { SafeAreaView, StyleSheet } from "react-native";
import Search from "./Component/Search";
export default class App extends Component {
render() {
return (
<SafeAreaView style={styles.container}>
<Search />
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
}
});
import React from "react";
import { View, TextInput, Button, FlatList, StyleSheet } from "react-native";
import LivreItem from "../Component/LivreItem";
class Search extends React.Component {
constructor(props) {
super(props);
this.inputValue = "";
this.state = { livres: [] };
}
searchBooks = async () => {
const key = "&key=XXXXXXXXXXXXXXXXXXXXXXX";
const url = "https://www.googleapis.com/books/v1/volumes?q=" + this.inputValue + key;
return fetch(url)
.then(response => response.json())
.catch(e => {
console.log("Une erreur s'est produite");
console.log(e);
});
};
getBooks = () => {
if (this.inputValue.length > 0) {
this.searchBooks()
.then(data => this.setState({ livres: data.items }))
.catch(reject => console.log(reject));
}
};
changeText = text => {
this.inputValue = text;
};
render() {
return (
<View style={styles.header_container}>
<View style={styles.sub_container}>
<TextInput
onChangeText={text => this.changeText(text)}
style={styles.input}
placeholder="Ex: Harry Potter"
/>
<Button
style={styles.button}
title="Rechercher"
onPress={() => this.getBooks()}
/>
</View>
<FlatList
style={styles.list}
data={this.state.livres}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <LivreItem livre={item.volumeInfo} />}
/>
</View>
);
}
}
const styles = StyleSheet.create({
sub_container: {
justifyContent: "space-between",
flexDirection: "row",
marginTop: 30,
paddingRight: 10,
paddingLeft: 10
},
header_container: {
flex: 1,
flexDirection: "column",
padding: 10
},
input: {
borderRadius: 4,
borderWidth: 0.5,
borderColor: "#d6d7da",
width: 150,
paddingLeft: 5
},
button: {
borderRadius: 4
},
list: {
paddingLeft: 15,
paddingRight: 15
}
});
export default Search;
import React from "react";
import { View, StyleSheet, Image, Text } from "react-native";
class LivreItem extends React.Component {
constructor(props) {
super(props);
this.state = { livre: this.props.livre};
this.description =
this.state.livre.description === null || this.state.livre.description === undefined
? "Pas de description disponible"
: this.state.livre.description;
this.img = this.state.livre.imageLinks;
this.image =
this.img === undefined ||
this.img.smallThumbnail === undefined ||
this.img.smallThumbnail === null
? null
: this.state.livre.imageLinks.smallThumbnail;
}
render() {
return (
<View style={styles.content}>
<View>
<Image style={styles.image} source={{ uri: this.image }} />
<Image style={styles.image} source={this.image} />
</View>
<View style={styles.content_container}>
<Text style={styles.titre}>{this.state.livre.title}</Text>
<Text style={styles.description} numberOfLines={4}>
{this.description}
</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
content: {
height: 125,
flexDirection: "row",
marginTop: 15
},
content_container: {
flexDirection: "column",
flexShrink: 1,
marginLeft: 10
},
image: {
width: 100,
height: 100
},
titre: {
fontWeight: "bold",
flexWrap: "wrap"
},
description: {
flexWrap: "wrap"
}
});
export default LivreItem;
Thanks.
Configure the prop extraData in Flatlist component ala:
<FlatList
extraData={this.state.livres}
/>
Pass a boolean value to the FlatList extraData.
<FlatList
extraData={this.state.refresh}
/>
Related
function DateTimePick is a child function to render picked date and picked time in parent component Reservation. Currently there are two issues with the codes: 1. the form in Reservation does not reset after submit data. 2. child DateTimePick fails to update the state for 'date' and 'time' in parent Reservation. Please have a look and lemme know how to fix these. Thanks.
child function DateTimePick is below:
import React, {useState} from 'react';
import {View, Button, Platform, Text, TextInput, StyleSheet} from 'react-native';
import DateTimePicker from '#react-native-community/datetimepicker';
import { Icon } from 'react-native-elements';
import Moment from "moment";
export const DateTimePick = () => {
const [date, setDate] = useState(new Date());
const [mode, setMode] = useState('date');
const [show, setShow] = useState(false);
const onChange = (event, selectedDate) => {
const currentDate = selectedDate || date;
setShow(Platform.OS === 'ios');
setDate(currentDate);
};
const showMode = (currentMode) => {
setShow(true);
setMode(currentMode);
};
const showDatepicker = () => {
showMode('date');
};
const showTimepicker = () => {
showMode('time');
};
return (
<View>
<View style={styles.formRow}>
<Text style={styles.formLabel}> Date</Text>
<Text onPress={showDatepicker} style={styles.formItem} value_date={date.toDateString()} onChange = {(value_date) => this.props.setState({date: value_date})}><Icon type='font-awesome-5' name='calendar' color='#512DA8' />{' ' + Moment(date).format('DD-MMM-YYYY') }</Text>
</View>
<View style={styles.formRow}>
<Text style={styles.formLabel}> Time</Text>
<Text onPress={showTimepicker} style={styles.formItem} value_time={date.toTimeString()} onChange = {(value_time) => this.props.setState({time: value_time})}><Icon type='font-awesome-5' name='clock' color='#512DA8' /> {' ' + Moment(date).format('h:mm A') }</Text>
</View>
{show && (
<DateTimePicker
testID="dateTimePicker"
value={date}
mode={mode}
is24Hour={true}
display="default"
onChange={onChange}
/>
)}
</View>
);
};
//export default DateTimePick;
const styles = StyleSheet.create({
formRow: {
alignItems: 'center',
justifyContent: 'center',
flex: 1,
flexDirection: 'row',
margin: 20
},
formLabel: {
fontSize: 18,
flex: 1
},
formItem: {
flex: 1
},
modal: {
justifyContent: 'center',
margin: 20
},
modalTitle: {
fontSize: 24,
fontWeight: 'bold',
backgroundColor: '#512DA8',
textAlign: 'center',
color: 'white',
marginBottom: 20
},
modalText: {
fontSize: 18,
margin: 10
},
})
parent Reservation which produces a reservation form and a reservation input confirmed modal
import React, {Component} from 'react';
import { Text, View, ScrollView, StyleSheet, Switch, Button, TextInput, Modal} from 'react-native';
import {DateTimePick} from './DateTimePickComponent';
class Reservation extends Component {
constructor(props) {
super(props);
this.state = {
guests: 1,
smoking: false,
notes:'',
date: new Date().toDateString(),
time: new Date().toTimeString(),
showModal: false
}
}
toggleModal() {
this.setState({showModal: !this.state.showModal})
}
handleReservation() {
console.log(JSON.stringify(this.state)); //log current state
//this.setState({ // reset the form
//})
this.toggleModal();
}
resetForm() {
this.setState({
guests: 1,
smoking: false,
notes:'',
date: new Date().toDateString(),
time: new Date().toTimeString(),
showModal: false
});
}
render() {
//, transform: [{ scaleX: 3 }, { scaleY: 1.5 }] => for switch
return(
<ScrollView>
<View style={styles.formRow}>
<Text style={styles.formLabel}> Guests </Text>
<TextInput style={styles.formItem} keyboardType="numeric" placeholder="Number"
value_guests={this.state.guests}
onChangeText = {(value_guests) => this.setState({guests: value_guests})} >
</TextInput>
</View>
<View style={styles.formRow}>
<Text style={styles.formLabel}> Notes </Text>
<TextInput style={styles.formItem} keyboardType="default" placeholder="Allergy,..etc"
value_notes={this.state.notes}
onChangeText = {(value_notes) => this.setState({notes: value_notes})} >
</TextInput>
</View>
<View style={styles.formRow}>
<Text style={styles.formLabel}> Non-Smoking </Text>
<Switch style={{ flex: 1, backgroundColor: "orange", paddingLeft:0, marginLeft:0 }} trackColor={{true: 'red', false: 'grey'}}
value={this.state.smoking}
onValueChange = {(value) => this.setState({smoking: value})} />
<Text style={styles.formLabel}> Smoking </Text>
</View>
<DateTimePick />
<View style={styles.formRow}>
<Button
onPress={() => this.handleReservation()}
title="Reserve"
color="#512DA8"
accessibilityLabel="Learn more about this purple button"
/>
</View>
<Modal animationType={'slide'} transparent={false} visible={this.state.showModal}
onDismiss={() => {this.toggleModal()}}
onRequestClose={() => {this.toggleModal()}}>
<View style={styles.modal}>
<Text style={styles.modalTitle}>Your Reservation</Text>
<Text style={styles.modalText}>Number of Guests: {this.state.guests}</Text>
<Text style={styles.modalText}>Notes: {this.state.notes}</Text>
<Text style = {styles.modalText}>Smoking?: {this.state.smoking ? 'Yes' : 'No'}</Text>
<Text style = {styles.modalText}>Date and Time: {this.state.date} {this.state.time}</Text>
<Button
onPress = {() =>{this.toggleModal(); this.resetForm();}}
color="#512DA8"
title="Close"
/>
</View>
</Modal>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
formRow: {
alignItems: 'center',
justifyContent: 'center',
flex: 1,
flexDirection: 'row',
margin: 20
},
formLabel: {
fontSize: 18,
flex: 1
},
formItem: {
flex: 1
},
modal: {
justifyContent: 'center',
margin: 20
},
modalTitle: {
fontSize: 24,
fontWeight: 'bold',
backgroundColor: '#512DA8',
textAlign: 'center',
color: 'white',
marginBottom: 20
},
modalText: {
fontSize: 18,
margin: 10
},
})
export default Reservation;
you could fix it by transfering state consts date, show, mode to parent Reservation
then pass state change functions to the DateTimePick component in props like below
<DateTimePick onDateChange={(date) => this.setState({date: date}) } />
and in DateTimePick component:
const onChange = (event, selectedDate) => {
const currentDate = selectedDate || date;
setShow(Platform.OS === 'ios');
props.onDateChange(currentDate);
};
also dont forget to pass props in the component like
export const DateTimePick = (props) => {
Solved it. For using child data to update parents' state need to pass a handler for setting the state of parent to child, refer How to update parent's state in React?
class Parent extends React.Component {
constructor(props) {
super(props)
this.handler = this.handler.bind(this)
}
handler() {
this.setState({
someVar: 'some value'
})
}
render() {
return <Child handler = {this.handler} />
}
}
class Child extends React.Component {
render() {
return <Button onClick = {this.props.handler}/ >
}
}
In implementation, a handler is inserted into parent class Reservation as below
...
class Reservation extends Component {
constructor(props) {
...
this.handler = this.handler.bind(this)
}
handler(selectedDate) {
this.setState({
date: Moment(selectedDate).format('DD-MMM-YYYY'),
time: Moment(selectedDate).format('h:mm A'),
})
}
...
In child DateTimePick, embed the handler in onChange to pass child update from onChange to state update in parent Reservation like this
...
export const DateTimePick = (props) => {
const handler = props.handler;
...
const onChange = (event, selectedDate) => {
...
handler(currentDate);
};
...
...
Here Home.js is Shows the both screen names
And Here Student.js screen is show only student contact numbers and Teacher.js
This is my full code..
And I have used navigation version 4
Navigation.js
import { createAppContainer } from 'react-navigation'
import { createStackNavigator } from 'react-navigation-stack'
import Home from '../screens/Home'
import Teacher from '../screens/Teacher'
import Student from '../screens/Student'
const StackNavigator = createStackNavigator(
{
Student: {
screen: Student
},
Home: {
screen: Home
},
Teacher: {
screen: Teacher
}
},
{
initialRouteName: 'Home',
headerMode: 'none',
mode: 'modal'
}
)
export default createAppContainer(StackNavigator)
Home.js
import React from 'react';
import { Text, View, TouchableOpacity, StyleSheet } from 'react-native';
export default class Home extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ marginTop: 50, fontSize: 25 }}>Home!</Text>
<View
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Teacher')}>
<Text>Teacher Numbers</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Student')}>
<Text>Student Numbers</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10,
width: 300,
marginTop: 16,
},
});
Student.js
import React, { useState } from 'react'
import { StyleSheet, View, Button, FlatList } from 'react-native'
import { Text, FAB, List, IconButton, Colors, TextInput } from 'react-native-paper'
import { useSelector, useDispatch } from 'react-redux'
import { addnumber, deletenumber } from './../store/actions/studentList'
import Header from '../components/Header'
function StudentNumber({ navigation }) {
const [studentNumber, setStudentNumber] = useState('')
const snumbers = useSelector(state => state)
const dispatch = useDispatch()
const addNumber = number => dispatch(adbnumber(number))
const deleteNumber = id => dispatch(deletenumber(id))
function onSaveNumber() {
addNumber({studentNumber})
}
function FlatListItemSeparator () {
return (
//Item Separator
<View style={{height: 0.5, width: '100%', backgroundColor: '#C8C8C8'}}/>
);
};
function GetItem(item) {
//Function for click on an item
Alert.alert(item);
}
return (
<>
<View style={styles.container}>
<Button title="Go back" onPress={() => navigation.goBack()} />
<TextInput
label='Add a Number Here'
value={studentNumber}
mode='outlined'
onChangeText={setStudentNumber}
style={styles.title}
/>
{bnumbers.length === 0 ? (
<View style={styles.titleContainer}>
<Text style={styles.title}>You do not have any student numbers</Text>
</View>
) : (
<FlatList
data={snumbers}
ItemSeparatorComponent={FlatListItemSeparator}
renderItem={({ item }) => (
<List.Item
title={item.number.studentNumber}
descriptionNumberOfLines={1}
titleStyle={styles.listTitle}
onPress={() => deletestudentNumber(item.bid)}
/>
)}
keyExtractor={item => item.id.toString()}
/>
)}
<FAB
style={styles.fab}
small
icon='plus'
label='Add new number'
onPress={() => onSaveNumber()}
/>
</View>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingHorizontal: 10,
paddingVertical: 20
},
titleContainer: {
alignItems: 'center',
justifyContent: 'center',
flex: 1
},
title: {
fontSize: 20
},
fab: {
position: 'absolute',
margin: 20,
right: 0,
bottom: 10
},
listTitle: {
fontSize: 20
}
})
export default Student
Teacher.js
import React, { useState } from 'react'
import { StyleSheet, View, Button, FlatList } from 'react-native'
import { Text, FAB, List, IconButton, Colors, TextInput } from 'react-native-paper'
import { useSelector, useDispatch } from 'react-redux'
import { addnumber, deletenumber } from './../store/actions/teacherList'
import Header from '../components/Header'
function Teacher({ navigation }) {
const [teacherNumber, setTeacherNumber] = useState('')
const numbers = useSelector(state => state)
const dispatch = useDispatch()
const addNumber = number => dispatch(addnumber(number))
const deleteNumber = id => dispatch(deletenumber(id))
function onSaveNumber() {
addNumber({ teacherNumber})
}
function FlatListItemSeparator () {
return (
//Item Separator
<View style={{height: 0.5, width: '100%', backgroundColor: '#C8C8C8'}}/>
);
};
function GetItem(item) {
//Function for click on an item
Alert.alert(item);
}
return (
<>
<View style={styles.container}>
<Button title="Go back" onPress={() => navigation.goBack()} />
<TextInput
label='Add a Number Here'
value={teacherNumber}
mode='outlined'
onChangeText={setTeacherNumber}
style={styles.title}
/>
{numbers.length === 0 ? (
<View style={styles.titleContainer}>
<Text style={styles.title}>You do not have any teacher numbers</Text>
</View>
) : (
<FlatList
data={numbers}
ItemSeparatorComponent={FlatListItemSeparator}
renderItem={({ item }) => (
<List.Item
title={item.number.teacherNumber}
descriptionNumberOfLines={1}
titleStyle={styles.listTitle}
onPress={() => deleteNumber(item.id)}
/>
)}
keyExtractor={item => item.id.toString()}
/>
)}
<FAB
style={styles.fab}
small
icon='plus'
label='Add new number'
onPress={() => onSaveNumber()}
/>
</View>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingHorizontal: 10,
paddingVertical: 20
},
titleContainer: {
alignItems: 'center',
justifyContent: 'center',
flex: 1
},
title: {
fontSize: 20
},
fab: {
position: 'absolute',
margin: 20,
right: 0,
bottom: 10
},
listTitle: {
fontSize: 20
}
})
export default Teacher
studentStore.js
import { createStore } from 'redux'
import studentReducer from '../actions/studentList'
const studentStore = createStore(studentReducer)
export default studentStore
teacherStore.js
import { createStore } from 'redux'
import teacherReducer from '../actions/teacherList'
const teacherStore = createStore(teacherReducer)
export default teacherStore
teacherReducer.js
import remove from 'lodash.remove'
export const ADD_NUMBER = 'ADD_NUMBER'
export const DELETE_NUMBER = 'DELETE_NUMBER'
let numberID = 0
export function addnumber(number) {
return {
type: ADD_NUMBER,
id: numberID++,
number
}
}
export function deletenumber(id) {
return {
type: DELETE_NUMBER,
payload: id
}
}
const initialState = []
function teacherReducer(state = initialState, action) {
switch (action.type) {
case ADD_NUMBER:
return [
...state,
{
id: action.id,
number: action.number
}
]
case DELETE_NUMBER:
const deletedNewArray = remove(state, obj => {
return obj.id != action.payload
})
return deletedNewArray
default:
return state
}
}
export default teacherReducer
studetnReducer.js
import remove from 'lodash.remove'
export const ADD_NUMBER = 'ADD_NUMBER'
export const DELETE_NUMBER = 'DELETE_NUMBER'
let numberID = 0
export function addnumber(number) {
return {
type: ADD_NUMBER,
id: numberID++,
number
}
}
export function deletenumber(id) {
return {
type: DELETE_NUMBER,
payload: id
}
}
const initialState = []
function studentReducer(state = initialState, action) {
switch (action.type) {
case ADD_NUMBER:
return [
...state,
{
id: action.id,
number: action.number
}
]
case DELETE_NUMBER:
const deletedNewArray = remove(state, obj => {
return obj.id != action.payload
})
return deletedNewArray
default:
return state
}
}
export default studentReducer
I Have tried this but is working only for Teachers not for both..
I use a FlatList to display search results.
<View>
<FlatList
data={this.state.films}
keyExtractor={(item) => item.id.toString()}
renderItem={({item}) => <FilmItem film={item}/>}
/>
</View>
However, when the user starts a second search, this list does not restart to index 0. So I would like to add ScrollToIndex or viewPosition. I tried this but it doesn't work :
<View>
<FlatList
data={this.state.films}
keyExtractor={(item) => item.id.toString()}
renderItem={({item}) => <FilmItem film={item}/>}
scrollToItem={(index) => {0}}
/>
</View>
Could you please explain me why this is wrong and what would be the best solution ?
Thanks a lot,
Try this... I made a bunch of changes and have put comments:
// Components/Search.js
import React from "react";
import {StyleSheet, View, TextInput, Button, Text, FlatList, ActivityIndicator} from "react-native";
import FilmItem from "./filmItem";
import {getFilmsFromApiWithSearchedText} from "../API/TMDBApi";
class Search extends React.Component {
flatListRef = null; // declaring this here to make it explicit that we have this available
constructor(props) {
super(props);
this.searchedText = "";
this.state = {
films: [],
isLoading: false,
};
}
_loadFilms = () => {
// needs to be an arrow function so `this` is bound to this component
this.scrollToIndex(); // assumed you meant to actually call this?
if (this.searchedText.length > 0) {
this.setState({isLoading: true});
getFilmsFromApiWithSearchedText(this.searchedText).then(data => {
this.setState({
films: data.results,
isLoading: false,
});
});
}
};
// needs arrow to use `this`
_searchTextInputChanged = text => {
this.searchedText = text;
};
// needs arrow to use `this`
_displayLoading = () => {
// better to return null if not loading, otherwise return loading indicator
if (!this.state.isLoading) return null;
return (
<View style={styles.loading_container}>
<ActivityIndicator size='large' />
</View>
);
};
scrollToIndex = () => {
// you previously had this inside another method
this.flatListRef && this.flatListRef.scrollToIndex({index: 1}); // checking it exists first
};
render() {
return (
<View style={styles.main_container}>
<TextInput
style={styles.textinput}
placeholder='Titre du film'
onChangeText={text => this._searchTextInputChanged(text)}
onSubmitEditing={this._loadFilms} // no need to create a new anonymous function here
/>
<Button title='Rechercher' onPress={this._loadFilms} />
<View>
<FlatList
data={this.state.films}
ref={ref => (this.flatListRef = ref)}
keyExtractor={item => item.id.toString()}
onEndReachedThreshold={1} // corrected typo
onEndReached={() => {
console.log("TOC");
}}
renderItem={({item}) => <FilmItem film={item} />}
/>
</View>
{this._displayLoading()}
</View>
);
}
}
const styles = StyleSheet.create({
main_container: {
marginTop: 60,
padding: 15,
flex: 1,
},
loading_container: {
position: "absolute",
left: 0,
right: 0,
top: 100,
bottom: 0,
alignItems: "center",
paddingTop: 50,
backgroundColor: "white",
},
textinput: {
height: 50,
borderColor: "#999999",
borderWidth: 1,
paddingLeft: 5,
},
});
export default Search;
Using this code as example:
import React, { Component } from 'react';
import { Text, View, FlatList, Dimensions, Button, StyleSheet } from 'react-native';
const { width } = Dimensions.get('window');
const style = {
justifyContent: 'center',
alignItems: 'center',
width: width,
height: 50,
flex: 1,
borderWidth: 1,
};
const COLORS = ['deepskyblue','fuchsia', 'lightblue '];
function getData(number) {
let data = [];
for(var i=0; i<number; ++i)
{
data.push("" + i);
}
return data;
}
class ScrollToExample extends Component {
getItemLayout = (data, index) => (
{ length: 50, offset: 50 * index, index }
)
getColor(index) {
const mod = index%3;
return COLORS[mod];
}
scrollToIndex = () => {
let randomIndex = Math.floor(Math.random(Date.now()) * this.props.data.length);
this.flatListRef.scrollToIndex({animated: true, index: randomIndex});
}
scrollToItem = () => {
let randomIndex = Math.floor(Math.random(Date.now()) * this.props.data.length);
this.flatListRef.scrollToIndex({animated: true, index: "" + randomIndex});
}
render() {
return (
<View style={styles.container}>
<View style={styles.header}>
<Button
onPress={this.scrollToIndex}
title="Tap to scrollToIndex"
color="darkblue"
/>
<Button
onPress={this.scrollToItem}
title="Tap to scrollToItem"
color="purple"
/>
</View>
<FlatList
style={{ flex: 1 }}
ref={(ref) => { this.flatListRef = ref; }}
keyExtractor={item => item}
getItemLayout={this.getItemLayout}
initialScrollIndex={50}
initialNumToRender={2}
renderItem={({ item, index}) => (
<View style={{...style, backgroundColor: this.getColor(index)}}>
<Text>{item}</Text>
</View>
)}
{...this.props}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
header: {
paddingTop: 20,
backgroundColor: 'darkturquoise',
alignItems: 'center',
justifyContent: 'center'
}
});
export default class app extends Component {
render() {
return <ScrollToExample
data={getData(100)}
/>
}
}
I tried to add a ref but it doesn't work :
// Components/Search.js
import React from 'react'
import { StyleSheet, View, TextInput, Button, Text, FlatList, ActivityIndicator } from 'react-native'
import FilmItem from './filmItem'
import { getFilmsFromApiWithSearchedText } from '../API/TMDBApi'
class Search extends React.Component {
constructor(props) {
super(props)
this.searchedText = ""
this.state = {
films: [],
isLoading: false,
}
}
_loadFilms() {
{this.scrollToIndex}
if (this.searchedText.length > 0) {
this.setState({isLoading: true})
getFilmsFromApiWithSearchedText(this.searchedText).then(data => {
this.setState({
films: data.results,
isLoading: false
})
})
}
}
_searchTextInputChanged(text) {
this.searchedText = text
}
_displayLoading() {
if (this.state.isLoading) {
return (
<View style={styles.loading_container}>
<ActivityIndicator size='large'/>
</View>
)
}
scrollToIndex = () => {
this.flatListRef.scrollToIndex({index: 1});
}
}
render() {
return (
<View style={styles.main_container}>
<TextInput
style={styles.textinput}
placeholder='Titre du film'
onChangeText={(text) => this._searchTextInputChanged(text)}
onSubmitEditing={() => this._loadFilms()}
/>
<Button title='Rechercher' onPress={() => this._loadFilms()} />
<View>
<FlatList
data={this.state.films}
ref={(ref) => { this.flatListRef = ref; }}
keyExtractor={(item) => item.id.toString()}
onEndReachedThreashold={1}
onEndReached={() => {console.log("TOC")}}
renderItem={({item}) => <FilmItem film={item}/>}
/>
</View>
{this._displayLoading()}
</View>
)
}
}
const styles = StyleSheet.create({
main_container: {
marginTop: 60,
padding: 15,
flex: 1,
},
loading_container: {
position: 'absolute',
left: 0,
right: 0,
top: 100,
bottom: 0,
alignItems: 'center',
paddingTop: 50,
backgroundColor: 'white',
},
textinput: {
height: 50,
borderColor: '#999999',
borderWidth: 1,
paddingLeft: 5,
}
})
export default Search
I'm sur I am doing something wrong, but don't find the error. Thanks a lot for your help.
I've a couple of buttons in my react native app, on pressing any button, color should change. Code is as given below
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
Button,
TouchableHighlight,
Image,
Alert
} from 'react-native';
export default class Home extends Component {
constructor(props) {
super(props);
this.state= {
clicks: 0,
show: true,
isbuttonpress: false
};
}
onButtonState = () => {
this.setState({isbuttonpress: true});
}
render() {
return (
<View style={ [styles.container] }>
<Text style= { [styles.header] }>How likely is it that you would recommend this company to a friend or colleague?</Text>
<TouchableHighlight style = { [styles.buttonContainer, this.state.isbuttonpress?styles.gobackred:styles.goback] } onPress = { () => this.onButtonState() }>
<Text style = { styles.gobacktext }>0</Text>
</TouchableHighlight>
<TouchableHighlight style = { [styles.buttonContainer, this.state.isbuttonpress?styles.gobackred:styles.goback] } onPress = { () => this.onButtonState() }>
<Text style = { styles.gobacktext }>1</Text>
</TouchableHighlight>
<TouchableHighlight style = { [styles.buttonContainer, this.state.isbuttonpress?styles.gobackred:styles.goback] } onPress = { () => this.onButtonState() }>
<Text style = { styles.gobacktext }>2</Text>
</TouchableHighlight>
<TouchableHighlight style = { [styles.buttonContainer, this.state.isbuttonpress?styles.gobackred:styles.goback] } onPress = { () => this.onButtonState() }>
<Text style = { styles.gobacktext }>3</Text>
</TouchableHighlight>
<TouchableHighlight style = { [styles.buttonContainer, this.state.isbuttonpress?styles.gobackred:styles.goback] } onPress = { () => this.onButtonState() }>
<Text style = { styles.gobacktext }>4</Text>
</TouchableHighlight>
<TouchableHighlight style = { [styles.buttonContainer, this.state.isbuttonpress?styles.gobackred:styles.goback] } onPress = { () => this.onButtonState() }>
<Text style = { styles.gobacktext }>5</Text>
</TouchableHighlight>
<TouchableHighlight style = { [styles.nextContainer, styles.goback] } onPress = { () => this.onNextButtonState() }>
<Text style = { styles.gobacktext }>Next</Text>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
header: {
fontSize: 20,
alignItems: 'center',
padding: 20,
},
container: {
alignItems: 'center',
justifyContent: 'center'
},
buttonContainer: {
height:45,
justifyContent: 'center',
alignItems: 'center',
marginBottom:20,
width:45,
}, gobackred: {
backgroundColor: "#00a2b2",
},
goback: {
backgroundColor: "#00b5ec",
},
gobacktext: {
color: 'white',
},
nextContainer: {
height:45,
marginTop: 15,
justifyContent: 'center',
alignItems: 'center',
marginBottom:20,
width:250,
borderRadius:30,
}
})
Layout is as given below:
Whenever any option is selected, color of that button should change. But in my code, color of all buttons changes when clicked on any button. How can I fix it?
This happens because you used one state this.state.isbuttonpress for all button try to make the component of this code.
your TouchableHighlight Component
DemoButton.js
import React, { Component } from "react";
import { View, Text, TouchableHighlight } from "react-native";
export default class DemoButton extends Component {
constructor(props) {
super(props);
this.state = { isbuttonpress: false };
}
onButtonState = () => {
this.setState({ isbuttonpress: !this.state.isbuttonpress });
};
render() {
return (
<View>
<TouchableHighlight
style={{ backgroundColor: this.state.isbuttonpress ? "red" : "blue" }}
onPress={this.onButtonState}
>
<Text>{this.props.buttonTitle}</Text>
</TouchableHighlight>
</View>
);
}
}
App.js
import DemoButton from "./DemoButton";
export default class Heal extends Component {
constructor(props) {
super(props);
this.state = { isbuttonpress: false };
}
render() {
return (
<View>
<Header />
<DemoButton buttonTitle="0"/>
<DemoButton buttonTitle="1"/>
<DemoButton buttonTitle="2"/>
<DemoButton buttonTitle="3"/>
<DemoButton buttonTitle="4"/>
<DemoButton buttonTitle="5"/>
</View>
)
}
}
export const Artists = [
{
name: "Breakbot",
songs: [
{
title: "Star Tripper",
album: "Still Waters",
},
{
title: "You Should Know (feat. Ruckazoid)",
album: "Still Waters",
},
]
},]
Above is mock data array which is defined in another file. And I have declared flatlist in another file.
SmapleScreen.js
import React, { Component } from 'react'
import { Text, View, FlatList, TouchableOpacity, RefreshControl } from 'react-native'
import { connect } from 'react-redux'
// Add Actions - replace 'Your' with whatever your reducer is called :)
import Icon from 'react-native-vector-icons/MaterialIcons';
import { Fonts, Colors, Images, Metrics } from '../Themes'
import MockData from "./mockData"
// Styles
import styles from './Styles/OrdersScreenStyle'
class SampleScreen extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentWillMount() {
}
render() {
// console.log(this.props.order_details.new_orders,'refreshed' )
return (
(this.props.order_details.new_orders == null || this.props.order_details.new_orders.length == 0) ?
<View style={{ flex: 1, justifyContent: "center", backgroundColor: Colors.snow }}>
<Text style={{ alignSelf: 'center' }}>
You do not have any orders.
</Text>
</View>
:
<View style={{ flex: 1, flexDirection: 'column', justifyContent: "flex-start" }}>
<View style={{ padding: 10, flexDirection: 'row' }}>
<Text style={{ flex: 3 }}>Scheme</Text>
<Text style={{ flex: 2 }}>Amount</Text>
</View >
<FlatList
style={styles.container}
data={MockData}
keyExtractor={(item, index) => index}
renderItem={(item) => this.getOrderComponent(item)}
/>
<View>
<PrimaryButton label="Make Payment"
disabled={this.props.submitFetching} fetching={this.props.submitFetching} onPress={this.onMakePaymentClick} />
</View >
</View>
)
}
getOrderComponent=(item)=>{
return (
<View>
<Text>{item.name}</Text>
</View>
)
}
}
const mapStateToProps = (state, ownProps) => {
return {
}
}
const mapDispatchToProps = (dispatch) => ({
})
export default connect(mapStateToProps, mapDispatchToProps)(SmapleScreen)
MockData.js
const data =[
{
name: "Breakbot",
songs: [
{
title: "Star Tripper",
album: "Still Waters",
},
{
title: "You Should Know (feat. Ruckazoid)",
album: "Still Waters",
},
]
},
]
export default data