React Native Change List background color onPress



我想更改列表中唯一一个项目的背景色

目前我能够通过分配颜色来改变背景颜色取决于一个道具

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

最新更新