The intended functionality is as follows:
- Select an item in the list by pressing (calls
onPressSport()
) - The item's value is stored in the
sport
state - When the next button is pressed,
onPressNext()
is called (which calls a function from context)
The problem occurs in Step 3 when I log the value of sport
. Before onPressNext()
is called, the value is logged as a non-NULL value; however, the log within onPressNext()
is always null
.
Here is the code:
import React, { useEffect, useState, useContext } from 'react'
import {
StyleSheet,
Text,
View,
Pressable,
TextInput,
KeyboardAvoidingView,
FlatList,
} from 'react-native'
import { Feather } from '@expo/vector-icons'
import userContext from '../../context/user/userContext'
import gameContext from '../../context/game/gameContext'
import { SPORTS } from '../../sample_data'
import { doHaptics } from '../../functions'
import ErrorAlert from '../../ErrorAlert'
const CreateGame_Sport = ({navigation, route}) => {
const {game, new_selectSport} = useContext(gameContext)
// const {sport} = game
const [search, setSearch] = useState('')
const [results, setResults] = useState([])
const [error, setError] = useState(null)
const [sport, setSport] = useState(game?.sport || null)
useEffect(() => {
navigation.setOptions({
title: 'Pick a sport',
headerLeft: () => (
<Pressable style={hStyles.backButton} onPress={onPressBack} hitSlop={16}>
<Feather name="chevron-left" size={28} color="#212121"/>
</Pressable>
),
headerRight: () => (
<Pressable style={hStyles.nextButton} onPress={onPressNext} hitSlop={16}>
<Text style={hStyles.nextButtonText}>Next</Text>
</Pressable>
),
})
}, [navigation])
useEffect(() => {
if (!search)
return setResults([])
const filtered = SPORTS.filter(({name}) => name.toLowerCase().includes(search.toLowerCase()))
setResults(filtered)
}, [search])
useEffect(() => {
console.log('Sport updated!')
console.log(sport)
}, [sport])
const onPressBack = () => navigation.pop()
const onPressClear = () => {
setSearch('')
setResults([])
}
const onPressSport = (val) => setSport(val)
const onPressNext = async () => {
console.log('sport: ', sport)
if (!sport) {
await doHaptics('medium')
return setError('Please select a sport!')
}
new_selectSport(sport)
return navigation.push('CreateGame_Type')
}
const onEndReached = async () => {}
const renderItem = ({item}, index) => {
const {_id, name, icon: Icon} = item
const selected = sport?._id === _id
return (
<Pressable style={selected ? styles.resultAdded : styles.result} onPress={() => onPressSport(item)}
key={_id}>
<View style={styles.resultColumn}>
<Text style={styles.resultName}>{name}</Text>
</View>
<Icon style={styles.resultIcon}/>
</Pressable>
)
}
return (
<KeyboardAvoidingView style={styles.container} verticalOffset={64}>
<ErrorAlert error={error} setError={setError}/>
<View style={styles.searchContainer}>
<Feather name="search" size={18} color="#808080" style={styles.searchIcon}/>
<TextInput
style={styles.searchInput}
value={search}
defaultValue={search}
onChangeText={value => setSearch(value)}
placeholder="Search by name..."
placeholderTextColor="#808080"
returnKeyType="default"
spellCheck={true}
/>
{search ? (
<Pressable style={styles.searchClearButton} onPress={onPressClear}>
<Feather name="x" size={12} color="#eee"/>
</Pressable>
) : null}
</View>
{search ? results ? (
<FlatList
data={results}
extraData={sport}
renderItem={renderItem}
keyExtractor={(item, index) => item.key}
initialNumToRender={16}
onEndReached={onEndReached}
contentContainerStyle={styles.scrollContainer}
/>
) : null : (
<FlatList
data={SPORTS}
extraData={sport}
renderItem={renderItem}
keyExtractor={(item, index) => index.toString()}
initialNumToRender={16}
onEndReached={onEndReached}
contentContainerStyle={styles.scrollContainer}
/>
)}
</KeyboardAvoidingView>
)
}
export default CreateGame_Sport
Any and all suggestions are welcome! :)