React Navigation 仅在第二次导航后设置参数
React Navigation only sets param after navigating a second time
我想从 Flastlist 传递项目(资产)并显示在 child 屏幕中。
但是当我按下该项目时,参数为空。我必须返回并再次按下它才能设置参数。如果我按下不同的项目,旧项目仍然存在,直到我第二次按下新项目。
我不知道 useEffect 是否是最好的方法。我只是在尝试不同的方法,但对 useEffect、useFocusEffect 或 none.
没有任何运气
Parent 与 Flastlist
export default function SitesScreen(props) {
const [sites, setSites] = useState(["Power Plant", "Paper Mill", "Plastic Injection"])
const [selectedItem, setSelectedItem] = useState(null)
const Item = ({ item, onPress }) => (
<TouchableOpacity onPress={onPress} style={[styles.item]} >
<Text style={styles.text}>{item}</Text>
</TouchableOpacity>
)
const renderItem = ({ item }) => {
return (
<View style={styles.itemContainer} >
<Item
item={item}
onPress={() => onItemSelected(item)}
/>
</View >
)
}
const onItemSelected = (item) => {
setSelectedItem(item)
props.navigation.navigate("Asset", { asset: selectedItem })
}
return (
<View style={styles.container}>
<CustomHeader title="Sites" navigation={props.navigation} isHome={true} ></CustomHeader>
<View style={styles.contentContainer}>
<View style={{ width: '90%', height: '50%', alignItems: 'center', bottom: -150 }} >
<FlatList
data={sites}
renderItem={renderItem}
keyExtractor={(item) => JSON.stringify(item)}
/>
</View>
</View>
</View>
)}
Child 显示项目的屏幕
export default function SitesScreen(props) {
const [asset, setAsset] = useState('')
useEffect(() => {
setAsset(props.route.params.asset)
console.log(asset)
}, [])
return (
<View style={styles.container}>
<CustomHeader title="Asset" navigation={props.navigation} isHome={false} ></CustomHeader>
<View style={styles.contentContainer}>
<Text style={styles.text} >{asset}</Text>
<View style={{ width: '90%', height: '50%', alignItems: 'center', bottom: -150 }} >
</View>
</View>
</View>
)}
当您将 selectedItem
值作为参数传递到下一个屏幕时,从 setSelectedItem
设置的新状态尚未应用于组件。由于尚未应用新状态,您仍在传递为 selectedItem
设置的初始 null
值。发生这种情况是因为 函数基于其当前闭包使用状态值。
有关此问题的更详细说明,请参阅 。
问题已解决。
父屏幕需要在 useEffect 挂钩中有导航操作,而不是在 onItemSelected 函数中。这样它会等到状态被更改后再导航。
useEffect(() => {
if (selectedItem) {
props.navigation.navigate("Asset", { asset: selectedItem })
}
}, [selectedItem])
我想从 Flastlist 传递项目(资产)并显示在 child 屏幕中。 但是当我按下该项目时,参数为空。我必须返回并再次按下它才能设置参数。如果我按下不同的项目,旧项目仍然存在,直到我第二次按下新项目。 我不知道 useEffect 是否是最好的方法。我只是在尝试不同的方法,但对 useEffect、useFocusEffect 或 none.
没有任何运气Parent 与 Flastlist
export default function SitesScreen(props) {
const [sites, setSites] = useState(["Power Plant", "Paper Mill", "Plastic Injection"])
const [selectedItem, setSelectedItem] = useState(null)
const Item = ({ item, onPress }) => (
<TouchableOpacity onPress={onPress} style={[styles.item]} >
<Text style={styles.text}>{item}</Text>
</TouchableOpacity>
)
const renderItem = ({ item }) => {
return (
<View style={styles.itemContainer} >
<Item
item={item}
onPress={() => onItemSelected(item)}
/>
</View >
)
}
const onItemSelected = (item) => {
setSelectedItem(item)
props.navigation.navigate("Asset", { asset: selectedItem })
}
return (
<View style={styles.container}>
<CustomHeader title="Sites" navigation={props.navigation} isHome={true} ></CustomHeader>
<View style={styles.contentContainer}>
<View style={{ width: '90%', height: '50%', alignItems: 'center', bottom: -150 }} >
<FlatList
data={sites}
renderItem={renderItem}
keyExtractor={(item) => JSON.stringify(item)}
/>
</View>
</View>
</View>
)}
Child 显示项目的屏幕
export default function SitesScreen(props) {
const [asset, setAsset] = useState('')
useEffect(() => {
setAsset(props.route.params.asset)
console.log(asset)
}, [])
return (
<View style={styles.container}>
<CustomHeader title="Asset" navigation={props.navigation} isHome={false} ></CustomHeader>
<View style={styles.contentContainer}>
<Text style={styles.text} >{asset}</Text>
<View style={{ width: '90%', height: '50%', alignItems: 'center', bottom: -150 }} >
</View>
</View>
</View>
)}
当您将 selectedItem
值作为参数传递到下一个屏幕时,从 setSelectedItem
设置的新状态尚未应用于组件。由于尚未应用新状态,您仍在传递为 selectedItem
设置的初始 null
值。发生这种情况是因为 函数基于其当前闭包使用状态值。
有关此问题的更详细说明,请参阅
问题已解决。
父屏幕需要在 useEffect 挂钩中有导航操作,而不是在 onItemSelected 函数中。这样它会等到状态被更改后再导航。
useEffect(() => {
if (selectedItem) {
props.navigation.navigate("Asset", { asset: selectedItem })
}
}, [selectedItem])