我想更改列表中唯一一个项目的背景色
目前我能够通过分配颜色来改变背景颜色取决于一个道具
activeColor = props.name === name ? 'red' : 'grey';
但是当我从列表中选择item时它会改变背景颜色并保存
这是我的尝试零食链接"在android上运行">
我已经改变了结构,在父组件中为选定的Item创建状态,并将其作为道具传递给子组件,同时使用setState方法
零食链接:https://snack.expo.dev/@ashwith00/biased-coffee
代码:
import * as React from 'react';
import { Text, View, StyleSheet, FlatList } from 'react-native';
import Constants from 'expo-constants';
import Example from './components/AssetExample';
let data = [
{
id: '1',
title: 'Card 1',
city: 'London',
},
{
id: '2',
title: 'Card 2',
city: 'London 2',
},
{
id: '3',
title: 'Card 3',
city: 'London 3',
},
{
id: '4',
title: 'Card 4',
city: 'London 4',
},
{
id: '5',
title: 'Card 5',
city: 'London 5',
},
];
export default function App() {
const [selectedItem, setSelectedItem] = React.useState(null);
return (
<View style={styles.container}>
{data.map((item) => (
<Example
title={item.title}
name={item.city}
key={item.id}
{...{ selectedItem, setSelectedItem }}
/>
))}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 80,
},
});
import React, { useState } from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
export type ExampleProps = {
title: string,
name: string,
selectedItem: any,
setSelectedItem: React.Dispatch<React.SetStateAction<any>>,
};
let activeColor: string;
const Example = (props: ExampleProps) => {
const { selectedItem, setSelectedItem } = props;
const activeColor = React.useMemo(
() => (props.name === selectedItem ? 'red' : 'grey'),
[props.name, selectedItem]
);
const onPlay = async () => {
setSelectedItem(props.name);
};
return (
<TouchableOpacity onPress={onPlay}>
<View style={[styles.row, { backgroundColor: activeColor }]}>
<View style={[styles.cell, { flex: 1 }]}>
<Text style={styles.title}>{props.title}</Text>
<Text style={styles.name}>{props.name}</Text>
</View>
</View>
</TouchableOpacity>
);
};
export default Example;
const styles = StyleSheet.create({
row: {
flexDirection: 'row',
marginBottom: 10,
},
cell: {
padding: 16,
justifyContent: 'center',
},
name: {
color: 'black',
},
title: {
color: 'black',
},
});
您必须全局管理状态,或者在本例中通过父组件管理状态。你的代码不能工作是因为子组件的一个实例"AssetExample.js"无法访问另一个"资产示例.js"的状态。子组件。
我已经一步一步地说明如何修改你的示例代码来实现你想要的。我相信,如果你按照这些步骤来做,可能会帮助你理解它应该如何工作。
1。在"AssetExample.js"中再添加两个Props .
我们想要管理依赖于父组件的子组件状态(父组件的一个子组件导致另一个子组件改变)。
因此,"点击"的逻辑组件和更新"isSelected"State应该由父组件管理。同时,传递道具&;isselected &;让子组件基于它的"被选中"重新呈现。状态(并更改背景颜色)。
export type ExampleProps = {
title: string,
name: string,
onPress: ()=>{}, // <-- Implement this in the parent component
isSelected: boolean, // <-- Simple boolean value to determine the background color
};
2。根据"isSelected"确定背景颜色AssetExample.js">
isSelected将由父组件("App.js")更新。当它这样做时,它将导致子组件("AssetExample.js")重新呈现。背景颜色(activeColor变量)将根据"isSelected"价值。
activeColor = props.isSelected ? 'red' : 'grey';
3。将onPress方法改为props。onPress in "AssetExample.js">
- 注意它是props。onPress NOT props.onPress()
<TouchableOpacity onPress={props.onPress}>
...
</TouchableOpacity>
4。在"App.js"中,添加状态来跟踪哪个项目已被选中。
我们使用"useState"钩子来跟踪从父组件中选择了哪个项。
const [selectedName, setSelectedName] = React.useState()
5。在"App.js"中,将以下道具添加到"> "组件
将props传递给子组件。
<Example
title={item.title}
name={item.city}
key={item.id}
onPress={() => setSelectedName(item.city)} // <-- Add this
isSelected={item.city===selectedName} // <-- Add this
/>
完整代码w/o data&styles - "App.js">
import * as React from 'react';
import { Text, View, StyleSheet, FlatList } from 'react-native';
import Constants from 'expo-constants';
import Example from './components/AssetExample';
let data = [...]; // REMOVED for readability
export default function App() {
const [selectedName, setSelectedName] = React.useState() // <-- Add this
return (
<View style={styles.container}>
{
data.map((item) => (
<Example
title={item.title}
name={item.city}
key={item.id}
onPress={() => setSelectedName(item.city)} // <-- Add this
isSelected={item.city===selectedName} // <-- Add this
/>
))
}
</View>
);
}
const styles = StyleSheet.create({ ... }); // REMOVED for readability
完整代码- "AssetExample.js">
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
export type ExampleProps = {
title: string,
name: string,
onPress: ()=>{}, // Add this
isSelected: boolean, // Add this
};
let activeColor: string;
const Example = (props: ExampleProps) => {
// You can remove this
// const [name, setName] = useState();
activeColor = props.isSelected ? 'red' : 'grey'; // Change this
// You can remove this
// const onPlay = async () => {
// setName(props.name);
// };
return (
<TouchableOpacity onPress={props.onPress}> // Change this
<View style={[styles.row, { backgroundColor: activeColor }]}>
<View style={[styles.cell, { flex: 1 }]}>
<Text style={styles.title}>{props.title}</Text>
<Text style={styles.name}>{props.name}</Text>
</View>
</View>
</TouchableOpacity>
);
};
export default Example;
const styles = StyleSheet.create({ ... }); // REMOVED for readability