React-Native how give a method an variable - react-native

I'm trying to change a variable in state so I give it to a component as property later on, but i can't seem to change the variable.
constructor(){
super();
this.state = {
dataSource: [],
reading: false,
iName: 'default'
};
this.startRead = this.startRead.bind(this);
}
startRead = ({item}) => {
this.setState({
reading: true,
iName: {item.name} //it doesn't work over here
});
}
renderItem = ({item}) => {
this.setName
return(
<TouchableOpacity style={{flex: 1, flexDirection: 'row', marginBottom: 5}} onPress={this.startRead}>
<Text>{item.name}</Text> // this does work
<Text>{item.desc}</Text>
</TouchableOpacity>
);
}
I called this renderItem function via a FlatList
this.state.reading ?
<ReadScreen iname={this.state.iName}/>
:
<View style={styles.slide}>
<FlatList
data={this.state.dataSource}
renderItem={this.renderItem}
/>
</View>
It gives me an error of
"SyntaxError: App.js: Unexpected token, expected ',' (21,24)"
(21,24) gives the line
iName: {item.name}
What am I doing wrong?
The goal is; when I press a Item of the FlatList, a.k.a. the TouchableOpacity, it renders the ReadScreen that shows, more given information through properties instead of the FlatList.
If it's unclear or need more information, just ask
Thank you for your time.

Replace this line
onPress={this.startRead}
With this line
onPress={() => this.startRead({item})}
Here's the full solution
renderItem = ({item}) => {
this.setName
return(
<TouchableOpacity style={{flex: 1, flexDirection: 'row', marginBottom: 5}} onPress={() => this.startRead({item})}>
<Text>{item.name}</Text> // this does work
<Text>{item.desc}</Text>
</TouchableOpacity>
);
}

Use iName: item.name instead of iName:{item.name}

Related

React Native TypeError: Cannot read property 'timeSlots' of undefined

I want to display the selected Date, Start Time, and End Time when user presses the Add Appointment Button. However, when I press the add appointment button, the data gets added to my database but it fails to show it on the FlatList.
Code snippet provided below (If full code is required I can provide it):
export default class FrCreateScreen extends Component {
addTimeDateAppt() {
let self = this;
AsyncStorage.getItem('my_token').then(keyValue => {
console.log('Freelancer Create Screen (keyValue): ', keyValue);
axios({
method: 'post',
url: Constants.API_URL + 'appointment_f/create_appointment/',
//responseType: 'json',
data: {
app_date_start: this.state.textAppointmentDate,
start_time: this.state.textAppointmentTime,
end_time: this.state.textEndTime,
},
headers: {
'X-API-KEY': Constants.API_KEY,
Authorization: keyValue,
},
})
.then(function(response) {
this.setState({
timeSlots: [
...this.state.timeSlots,
{
apptdate: this.state.textAppointmentDate,
appttime: this.state.textAppointmentTime,
endTime: this.state.textEndTime,
},
],
});
console.log(response.data);
})
.catch(function(error) {
console.log('Create Error: ', error);
});
});
}
deleteDateTime = id => {
const filteredData = this.state.timeSlots.filter(item => item.id !== id);
this.setState({ timeSlots: filteredData });
};
render() {
return (
<ScrollView>
{this.getAppointmentDatePage()}
{this.getAppointmentTimePage()}
{this.getEndTimePage()}
<TouchableOpacity
style={styles.addContainer}
onPress={() => this.addTimeDateAppt()}
>
<Text style={styles.addText}> Add Appointment </Text>
</TouchableOpacity>
<View>
<FlatList
data={this.state.timeSlots}
keyExtractor={({ id }, index) => index.toString()}
renderItem={({ item, index }) => {
return (
<View style={styles.containerList}>
<View style={styles.dateList}>
<Text style={{ fontWeight: 'bold' }}>Date: </Text>
<Text style={styles.textTime}>{item.apptdate}</Text>
</View>
<View style={styles.row}>
<View>
<Text style={{ fontWeight: 'bold' }}>Start Time:</Text>
<Text style={styles.textTime}>{item.appttime}</Text>
</View>
<View>
<Text style={{ fontWeight: 'bold' }}>End Time:</Text>
<Text style={styles.textTime}>{item.endTime}</Text>
</View>
<TouchableOpacity
onPress={() => this.deleteDateTime(item.index)}
>
<Feather name="trash" style={styles.icon} />
</TouchableOpacity>
</View>
</View>
);
}}
/>
</View>
</ScrollView>
);
}
}
Screenshot:
The error implies that 'state' doesn't exist.
Have you tried changing the method into an arrow function, i.e.
addTimeDateAppt = () => {...}
This will bind the method to the instance of your component, and references to 'this.state' will work.
Also you've declared the variable 'self' referring to 'this', but then proceed to use 'this' anyway in the method. Not sure if this is intentional but you shouldn't need it if you use the arrow syntax.

Why does object prop doesn't show in Flat List?

this.state={
task : "",
the_array : []
};
}
handleTextChange=(some_task) =>{
this.setState({
task : some_task
});
}
pushToList = () => {
let taskitem = {
name: this.state.task,
};
this.setState({
the_array: [...this.state.the_array, taskitem],
});
}
render() {
return(
<View style={{backgroundColor:'powderblue', height:'100%'}}>
<FlatList data = {this.state.the_array}
renderItem={(item) => <Text>{item.name}</Text>} keyExtractor={(item) => item.name} >
</FlatList>
<TextInput style={{ backgroundColor: 'lightsteelblue', height:60, borderRadius : 25, marginBottom:20}}
onChangeText={this.handleTextChange}>
</TextInput>
<TouchableOpacity style={{
backgroundColor: 'mediumpurple', height: 60, width: 80, alignSelf: 'center', borderRadius: 20, justifyContent: 'center',
alignItems: 'center', marginBottom:20
}} onPress={this.pushToList}>
This is my code.I'm trying to add Textinput content to Flatlist. For that purpose, I defined an object inside my button onPress method('pushToList'), named 'taskitem', and set a prop for it named 'name'.
'pushTolistMethod' is supposed to put the 'name' into the Flatlist on screen. but strangely it doesn't work and nothing happens when I press the button. I was wondering if anybody could help me with that.
Can you replace your flatlist code like this and try?
<FlatList data = {this.state.the_array}
renderItem={({ item }) => <Text>{item.name}</Text>} keyExtractor={(item) => item.name} >
</FlatList>
The data is on the item key so we use destructuring to access that from within the function.

React-native: how to highlight a flatlist item when it is touched

I have a flatlist and I want a background color to appear on an item in the list when it is touched. See image below; this is what should happen if I touch "game_name3":
But nothing happens; it stays looking like the screen on the left.
Here is my code:
constructor (props) {
super(props);
this.state = {
...
game_names: [
{game_name:"game_name1", players:4},
{game_name:"game_name2", players:4},
{game_name:"game_name3", players:4},
{game_name:"game_name4", players:4},
{game_name:"game_name5", players:4},
{game_name:"game_name6", players:4},
],
game_selected: '',
...
}
}
...
selectPublicGame = (game) => {
this.setState({game_selected: game});
}
renderItem = ({item}) => {
const unselected_game =
<View style={{flexDirection: 'row', flex: .5, justifyContent: 'space-between'}}>
<Text style={[styles.listText, styles.textPaddingHorizontal]}>
{item.game_name}
</Text>
<Text style={[styles.listText, styles.textPaddingHorizontal]}>
({item.players}/6)
</Text>
</View>;
const selected_game =
<View style={{flexDirection: 'row', flex: .5, justifyContent: 'space-between', backgroundColor: colors.JBTealTrans}}>
<Text style={[styles.listText, styles.textPaddingHorizontal]}>
{item.game_name}
</Text>
<Text style={[styles.listText, styles.textPaddingHorizontal]}>
({item.players}/6)
</Text>
</View>;
let selection;
if (item.game_name == this.state.game_selected) {
selection = selected_game
} else {
selection = unselected_game
}
return (
<TouchableWithoutFeedback
onPress={() => this.selectPublicGame(item.game_name)}
>
{selection}
</TouchableWithoutFeedback>
)
}
...
render() {
...
return(
...
<FlatList
data={this.state.game_names}
renderItem={this.renderItem}
keyExtractor={(item, index) => index.toString()}
/>
...
)
}
...
Each item in the flatlist is wrapped in TouchableWithoutFeedback, onPress sets the game_selected state to the game name that was selected. The items are conditionally rendered. If the game name is the same as the game_selected state, it should render the "selected_game" constant, which has the backgroundColor style, but is not doing anything for some reason.
FlatList is a pure component and only re-renders if strict equality checking on its data or extraData props returns false. Since your component rendering depends on state.game_selected that will need to be included in extraData:
<FlatList
data={this.state.game_names}
renderItem={this.renderItem}
keyExtractor={(item, index) => index.toString()}
extraData={this.state.game_selected}
/>

FlatList ref issue

I am not getting ref of the flatlist always getting
Warning: Function components cannot be given refs. Attempts to access
this ref will fail. Did you mean to use React.forwardRef()?
I am beginner in react-native
export default class ListData extends Component {
constructor(props) {
super(props);
this.state = {
flatListRef: null
};
}
render() {
return (
<View style={styles.container}>
<FlatList
data={countryList}
ref={ref => (this.state.flatListRef = ref)}
style={{ flex: 1 }}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
renderItem={({ item, index }) => (
<View style={[styles.ListViewContainer]}>
<Text style={styles.countryTxt}>
<Text> +{item.code}</Text>
<Text> {item.CountryName} </Text>
</Text>
</View>
)}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 40,
backgroundColor: "white"
}
});
Using import { FlatList } from "react-native"
instead of
import { FlatList } from 'react-native-gesture-handler';
is working. But I am still want to why it's not working with 'react-native-gesture-handler'. while list is displaying correctly but ref is not getting.
try this:
in your constructor
this.flatListRef = React.createRef()
and then in your FlatList you do:
<FlatList ref={this.flatListRef} ...
Try passing ref={null} to your list item component.
renderItem={({ item, index }) => (
<View style={[styles.ListViewContainer]} ref={null}>

Axios post with TextInput values not working with no trailing error

I am trying to pass some parameters from TextInput to the body in Axios. It doesn't display any error or return a status using console.log().
I have several ways to see what could have been the problem. I tried to pass the function to ComponentDiDMount and some other components lifecycles with no success. I have also passed the values directly, used Json.parse(), JSON.encode(), JSON.stringify(), no error and yet not returning status. I know there might be a mistake I am making.
More also, I don't know if I am doing this wrongly. I try to fetch data to a dropdown from which I need to use the key to pass the corresponding id of the selected value to category_id. When the page loads, it fetches "category" i.e a field name with corresponding id to the dropdown but only the corresponding is needed to pass to the Axios.post.
import React, { Component } from 'react';
import {
Text,
TextInput,
View,
Image,
TouchableOpacity,
Button,
StyleSheet} from 'react-native';
import { Dropdown } from 'react-native-material-dropdown';
import axios from 'axios';
export default class CreatePost extends Component {
constructor(props){
super(props)
this.state = {
category: [],
title: '',
cat: '',
author:'',
body:''
}
}
static navigationOptions = ()=> {
return{
title: null,
headerStyle: { backgroundColor: '#1A5276', color:'#fff' },
header:null
}
};
componentWillMount(){
axios.get(`http://localhost/rest_api_myblog/api/category/read.php`)
//.then(json => console.log(json.data.data[0].name))
.then(json => json.data.data)
.then(newData => this.setState({category: newData}))
.catch(error => alert(error))
}
onChangeTextPress(key, value){
this.setState((prevState) => {
//let selected = Object.assign({}, prevState.selected);
let selected = Object.assign({},prevState.selected);
selected[key] = value;
return { selected };
}, () => {
this.setState({ cat: this.state.selected[key]});
// console.log(cat);
});
}
onCreate = event => {
event.preventDefault();
const body = {
author :this.state.author,
title : this.state.title,
body : this.state.body,
category_id :this.state.cat
};
axios.post(`http://localhost/rest_api_myblog/api/post/create.php`, JSON.parse(body))
.then(res => {console.log(res)
})
.catch(e => console.log(e));
}
render() {
const data = this.state.category.map((cat, i) =>({
value: cat.name,
key: i
}));
return (
<View style= {styles.container}>
<View><Image style={styles.image} source={require('../images/blog.jpg')}/>
<Text style={styles.header}>Create Post</Text></View>
<View style={{alignItems:'center'}}>
<Text style= {styles.label}>Title</Text>
<TextInput
style={styles.textbox}
placeholder="Title"
onChangeText= {(title)=>{
this.setState({title});
}}
value={this.state.title}/>
<Text style= {styles.label}>Author</Text>
<TextInput
style={styles.textbox}
name='author'
placeholder="Author"
onChangeText= {(text)=>{
this.setState({author: text});
}}
value={this.state.author}
/>
<Text style= {styles.label}>Category</Text>
<Dropdown
dropdownOffset={{top:5, left: 0 }}
containerStyle={{
borderWidth:1,
borderColor:'lightgrey',
borderRadius:13, width:300, height: 40,
paddingLeft:6,
backgroundColor:'#fff'}}
rippleCentered={true}
inputContainerStyle={{ borderBottomColor: 'transparent' }}
data = {data}
valueExtractor={({value})=> value}
onChangeText={(value, key)=>{this.onChangeTextPress( value, key)}}
/>
<Text style= {styles.label}>Body</Text>
<TextInput
style={styles.textbox}
multiline = {true}
numberOfLines = {4}
placeholder="Body"
onChangeText= {(body)=>{
this.setState({body});
}}
value={this.state.body}
/>
<TouchableOpacity style={styles.buttonContainer}
onPress = {()=> {this.onCreate }}
>
<Text style={styles.buttonText}>Create</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
What I actually want is a post method based on the TextInput values entered by the users. More also, the corresponding ID of the selected dropdown value be passed instead of the actual value.
Thank you so much for your assistance.
From what I can read from the code, the problem seems to be in the way you call your onCreate method.
You are doing:
<TouchableOpacity style={styles.buttonContainer} onPress={()=> {this.onCreate }}>
<Text style={styles.buttonText}>Create</Text>
</TouchableOpacity>
Where you should be doing either:
<TouchableOpacity style={styles.buttonContainer} onPress={this.onCreate}>
<Text style={styles.buttonText}>Create</Text>
</TouchableOpacity>
Or:
<TouchableOpacity style={styles.buttonContainer} onPress={() => this.onCreate()}>
<Text style={styles.buttonText}>Create</Text>
</TouchableOpacity>