Searching doesn't change backgroundcolor - reactjs

I am trying to make a background color to change on my flatist whenever I press the search bar to make an input. When testing by making searchBarFocused:true an error pops up saying Undefined is not an object (evaluating 'this.state').
Here is the full code of the SearchScreen.js:
import React from 'react';
import { ScrollView, StyleSheet, TextInput, Text, View, FlatList, Keyboard, Image, TouchableOpacity, TouchableWithoutFeedback} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import * as Animatable from 'react-native-animatable';
const listItems = ['Meo Sudoeste', 'Vodafone Paredes de Coura', 'Super Bock Super Rock', 'NOS Primavera Sound', 'Rock in Rio', 'EDP Cool Jazz']
function SearchScreen({navigation}) {
state={
searchBarFocused: true
}
return (
<View style={styles.screen}>
<Animatable.View animation='slideInLeft' duration={500} style={styles.container}>
<Icon name='ios-search' style={styles.icon}/>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</Animatable.View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
//I took this part off because it is irrelevant
</ScrollView>
<FlatList
style={{backgroundColor:this.state.searchBarFocused?'rgba(0,0,0,0.3)':'white'}}
data = {listItems}
renderItem={({item}) => <Text style = {{ padding:20, fontSize:20}}>{item}</Text>}
keyExtractor={(item, index) => index.toString()}
/>
</View>
</View>
);
}
SearchScreen.navigationOptions = {
title: 'Procurar',
};
const styles = StyleSheet.create({
//Took this part off, its irrelevant
export default SearchScreen;
Why am I getting this error and can I correct it? Please help me

You're using functional component in your codebase, so you should use React Hooks to handle states.
import React, {useState} from 'react'
function SearchScreen({navigation}) {
const [searchBarFocused, setSearchBarFocused] = useState(false)
return (
<View style={styles.screen}>
<Animatable.View animation='slideInLeft' duration={500} style={styles.container}>
<Icon name='ios-search' style={styles.icon}/>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</Animatable.View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
//I took this part off because it is irrelevant
</ScrollView>
<FlatList
style={{backgroundColor:searchBarFocused?'rgba(0,0,0,0.3)':'white'}}
data = {listItems}
renderItem={({item}) => <Text style = {{ padding:20, fontSize:20}}>{item}</Text>}
keyExtractor={(item, index) => index.toString()}
/>
</View>
</View>
);
}
Otherwise, if you want to use Class components, then you can use class members as states.
class SearchScreen extends React.Component {
state={
searchBarFocused: true
}
return (
<View style={styles.screen}>
<Animatable.View animation='slideInLeft' duration={500} style={styles.container}>
<Icon name='ios-search' style={styles.icon}/>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</Animatable.View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
//I took this part off because it is irrelevant
</ScrollView>
<FlatList
style={{backgroundColor:this.state.searchBarFocused?'rgba(0,0,0,0.3)':'white'}}
data = {listItems}
renderItem={({item}) => <Text style = {{ padding:20, fontSize:20}}>{item}</Text>}
keyExtractor={(item, index) => index.toString()}
/>
</View>
</View>
);
}

to use this.state you should have a class based component or use Hook instead for your functional component

Related

How to get all inputs to reset on click of the reset form button

I am learning react and react native and trying to build a basic form. I want what is inputted in the inputs to be displayed below. Then on clicking the reset form button have all the inputs reset.
It is only resetting the first input and I can feel myself slowly grasping react but I am stuck on this last part. If someone could tell me how to fix this and explain the reasoning behind it it would be greatly appreciated.
Cheers
import React, {useState} from 'react';
import { Text, View, StyleSheet, Button, InputAccessoryView, TextInput} from 'react-native';
export default function Form() {
const inputAccessoryViewID = 'uniqueID';
const initialText='';
const[text, setText] = useState(initialText);
const[text2, setText2] = useState(initialText);
const[text3, setText3] = useState(initialText);
const[text4, setText4] = useState(initialText);
const[text5, setText5] = useState(initialText);
var onPressed = () =>{
setText(initialText);
}
return (
<View style={styles.container}>
<View style={styles.input}>
<TextInput inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText} value={text} placeholder={'First and Last Name'}/>
</View>
<View style={styles.input}>
<TextInput keyboardType="numeric" inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText2} value={text2} placeholder={'Phone Number'}/>
</View>
<View style={styles.input}>
<TextInput inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText3} value={text3} placeholder={'Program'}/>
</View>
<View style={styles.input}>
<TextInput inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText4} value={text4} placeholder={'Favourite Food'}/>
</View>
<View style={styles.input}>
<TextInput inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText5} value={text5} placeholder={'Hobby'}/>
</View>
<InputAccessoryView nativeID={inputAccessoryViewID}>
<Button
onPress={() => setText(initialText)}
title = "Reset Form"
/>
</InputAccessoryView>
<Text style={styles.displayText}>
{text}
</Text>
<Text style={styles.displayText}>
{text2}
</Text>
<Text style={styles.displayText}>
{text3}
</Text>
<Text style={styles.displayText}>
{text4}
</Text>
<Text style={styles.displayText}>
{text5}
</Text>
</View>
);
}
You would need to reset all states in the onPress:
import React, {useState} from 'react';
import { Text, View, StyleSheet, Button, InputAccessoryView, TextInput} from 'react-native';
export default function Form() {
const inputAccessoryViewID = 'uniqueID';
const initialText='';
const[text, setText] = useState(initialText);
const[text2, setText2] = useState(initialText);
const[text3, setText3] = useState(initialText);
const[text4, setText4] = useState(initialText);
const[text5, setText5] = useState(initialText);
return (
<View style={styles.container}>
<View style={styles.input}>
<TextInput inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText} value={text} placeholder={'First and Last Name'}/>
</View>
<View style={styles.input}>
<TextInput keyboardType="numeric" inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText2} value={text2} placeholder={'Phone Number'}/>
</View>
<View style={styles.input}>
<TextInput inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText3} value={text3} placeholder={'Program'}/>
</View>
<View style={styles.input}>
<TextInput inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText4} value={text4} placeholder={'Favourite Food'}/>
</View>
<View style={styles.input}>
<TextInput inputAccessoryViewID={inputAccessoryViewID} onChangeText={setText5} value={text5} placeholder={'Hobby'}/>
</View>
<InputAccessoryView nativeID={inputAccessoryViewID}>
<Button
onPress={() => {
setText(initialText);
setText2(initialText);
setText3(initialText);
setText4(initialText);
setText5(initialText);
}}
title = "Reset Form"
/>
</InputAccessoryView>
<Text style={styles.displayText}>
{text}
</Text>
<Text style={styles.displayText}>
{text2}
</Text>
<Text style={styles.displayText}>
{text3}
</Text>
<Text style={styles.displayText}>
{text4}
</Text>
<Text style={styles.displayText}>
{text5}
</Text>
</View>
);
}
This will reset all states to your initial text.
You could simplify your form state tracking and make it easier to reset by using useReducer instead of useState. With useReducer your entire form state could live in one place instead of being spread across a dozen different state variables.
If you go this route you can reset the form with a single call to dispatch(initialState).
Psuedocode:
const initialState = {
'First Name': '',
'Last Name': ''
'Favorite Food': '',
}
// just merges the "action" into the existing state
const reducer = (state, action) => ({...state, ...action});
const [state, dispatch] = useReducer(reducer, initialState);
return (
<View>
{
// create a text input for each key/value in initialState
Object.entries(initialState).map(([name, value]) => (
<TextInput
placeholder={name}
value={value}
onChangeText={newValue => dispatch({[name]: newValue})}
/>
))
}
<Button
onPress={() => dispatch(initialState)}
title = "Reset Form"
/>
</View>
)

Gesture Handler discontinued? RectButton dont workig (but its right)

I tried using ReactButton, but the onPress function doesn't run on click. All posts found on google are about not writing an arrow function in onPress, but that's not my mistake.
I don't know what it could be anymore, the function is not executed. I put a console.log inside to see if it appeared when clicking and nothing.
import * as React from 'react';
import { Text, StyleSheet, View, TextInput, ScrollView, Button } from 'react-native'
import { RectButton } from 'react-native-gesture-handler';
const SignIn = ({ navigation }) => {
return (
<ScrollView style={styles.scrollView}>
<Text style={styles.PageName}>SignIn</Text>
<View style={styles.form}>
<TextInput
placeholder="Email"
style={styles.input}
onChangeText={() => { }}
/>
<TextInput
placeholder="Password"
style={styles.input}
onChangeText={() => { }}
/>
<RectButton
style={styles.RectButton}
onPress={ () => navigation.navigate('Home') }
>
<View style={styles.button}>
<Text style={{ color: 'white' }}>SignIn</Text>
</View>
</RectButton>
<Text onPress={() => navigation.navigate('SignUp')}>Never SignUp? SignUp, click here.</Text>
</View>
</ScrollView>
);
};

How can i add images to the react-native-layout-grid? There are no props mentioned specifically in the Github repository

I am using the react-native-layout-grid package for displaying a grid layout. I want to add images in the grid layout instead of text/string. How can i do it?
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
} from 'react-native';
import GridLayout from 'react-native-layout-grid';
export default class App extends Component<{}> {
renderGridItem = (item) => (
<View style={styles.item}>
<View style={styles.flex} />
<Text style={styles.name}>
{item.name}
</Text>
</View>
);
render() {
const items = [];
for (let x = 1; x <= 30; x++) {
items.push({
name: `Grid ${x}`
});
}
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Grid Layout
</Text>
<View style={styles.flex}>
<GridLayout
items={items}
itemsPerRow={3}
renderItem={this.renderGridItem}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
///styles///
});
I need to add images instead of string texts being passed into props.Is there any way to do so? Thanks in advance.
In renderGridItem add the images
Eg:---
renderGridItem = (item) => (
<View style={styles.item}>
<View style={styles.flex} />
<Image
style={{width: 50, height: 50}}
source={{uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png'}}
/>
<Text style={styles.name}>
{item.name}
</Text>
</View>
);
working eg: https://snack.expo.io/#msbot01/petrified-tortillas

React Native child component not rendering on onPress event

I am trying to render the child component on onPressevent, the console.log works fine but components in the return function doesn't works.
Parent component:
onPress = (img,title,content) => {
this.setState({
show:true,
img:img,
title:title,
content:content
})
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem={({item}) => (
<TouchableOpacity
onPress={() => this.onPress(item.urlToImage,item.title,item.content)}
>
<View style={styles.picsCont}>
<Image style={styles.pics} source={{uri: item.urlToImage}}/>
<Text style={{color:'white', fontSize: 15, fontWeight: '700', paddingTop:10}}>
{item.title}
</Text>
</View>
</TouchableOpacity>
)}
keyExtractor={item => item.title}
/>
{this.state.show ?
<NewsView
img={this.state.img}
title={this.state.title}
content={this.state.content}
/> :
null
}
</View>
);
}
}
Child Component:
export default class NewsView extends Component {
render() {
console.log(this.props.img)
return (
<View style={styles.container}>
<Image style={styles.picsCont} source={{uri:this.props.img}} />
<Text style={styles.news}>{this.props.title}</Text>
<Text style={styles.news}>{this.props.content}</Text>
</View>
)
}
}
Thanks for the help...!
It might be the styles. If your child component has position:'absolute', it´s probably under your parent component, you can try to put on your child component view zIndex:10

Adding item click event in react native Grid View

Please find my code below and help me for adding item click listener for the items in the grid view. Please find the link which I followed library link.
And I need to display the name in an alert when the user clicks on each item in the gridlist. Styles are not included in the code
Thanks in Advance
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
TouchableWithoutFeedback
} from 'react-native';
import GridLayout from 'react-native-layout-grid';
class HomeScreen extends Component {
renderGridItem = (props) => (
<View style={styles.item} >
<View style={styles.flex} />
<Text style={styles.name} >
{props.name}
</Text>
</View>
);
render() {
const items = [];
for (let x = 1; x <= 30; x++) {
items.push({
name: `Grid ${x}`
});
}
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Grid Layout
</Text>
<View style={styles.flex}>
<GridLayout
items={items}
itemsPerRow={2}
renderItem={this.renderGridItem}>
</GridLayout>
</View>
</View>
);
}
}
export default HomeScreen;
Instead of using <View> in your renderGridItem, you could use one of the touchables component (react native doc).
For example with <TouchableOpacity >:
renderGridItem = (props) => (
<TouchableOpacity style={styles.item} onPress={() => this.showAlert(props.name)}>
<View style={styles.flex} />
<Text style={styles.name} >
{props.name}
</Text>
</TouchableOpacity>
);
showAlert = (name) => {
Alert.alert(
'Alert Title',
`The user name is: ${name}`,
[
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
}
Why don't you wrap renderGridItem in a TouchableWithoutFeedback?
renderGridItem = (props) => (
<TouchableWithoutFeedback onPress={()=> Alert.alert(props.name)}>
<View style={styles.item} >
<View style={styles.flex} />
<Text style={styles.name} >
{props.name}
</Text>
</View>
<TouchableWithoutFeedback />
);
Also you will need to import Alert from react-native.

Resources