javascript - 使用自定义按钮反应 Native FlatList,如何在点击时更改颜色?
问题描述
我创建了一个呈现名称的 FlatList。每行都有自己的按钮。单击按钮时,名称将添加到列表中,并且按钮应更改颜色
我的问题是,当我单击按钮时,按钮不会改变颜色,它只会在我对 FlatList 进行拉刷新时改变颜色
使用我的零食:https ://snack.expo.io/@thesvarta/92f850
这是我的组件
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
View,
Text,
FlatList,
StatusBar,
StyleSheet,
ActivityIndicator,
TouchableOpacity,
TouchableHighlight,
Image,
Button,
SearchBar,
TextInput,
} from 'react-native';
import TextDetails from '../TextDetails/TextDetails';
import { selectOptions } from '../store/actions/index';
class Search extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
page: 1,
error: null,
refreshing: false,
groupBy: '',
};
}
setFetch = () => {
this.setState(
{
groupBy: this.props.GroupBy,
},
() => {
this.makeRemoteRequest();
}
);
};
componentDidMount() {
this.setFetch();
}
makeRemoteRequest = () => {
const { page, groupBy } = this.state;
const url = `https://ollenorstrom.se/ollenorstrom.se/avoka/api/getOptions.php?page=${page}&row_per_page=5&group_by=${groupBy}`;
fetch(url)
.then(response => response.json())
.then(responseJson => {
this.setState(
{
data:
page == 1
? responseJson[0].DATA
: [...this.state.data, ...responseJson[0].DATA],
status: responseJson[0].STATUS,
message: responseJson[0].MESSAGE,
isLoading: false,
refreshing: false,
},
() => {}
);
});
};
handleRefresh = () => {
this.setState(
{
page: 1,
refreshing: true,
},
() => {
this.makeRemoteRequest();
}
);
};
handleLoadMore = () => {
this.setState(
{
page: this.state.page + 1,
},
() => {
this.makeRemoteRequest();
}
);
};
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '86%',
backgroundColor: '#CED0CE',
marginLeft: '14%',
}}
/>
);
};
inArray = (needle, haystack) => {
let length = haystack.length;
for (let i = 0; i < length; i++) {
if (haystack[i] == needle) return true;
}
return false;
};
renderRow = ({ item, index }) => {
return (
<View style={styles.ListContainer}>
<View style={styles.Text}>
<TextDetails Size={18}>{item.name}</TextDetails>
</View>
<View style={styles.button}>
<TouchableOpacity
style={
this.inArray(item.name, this.props.selectedOptions)
? styles.buttonOrange
: styles.buttonGray
}
onPress={() => this.props.onSelectOptions(item.name)}
/>
</View>
</View>
);
};
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View
style={{
paddingVertical: 20,
borderTopWidth: 1,
borderColor: '#CED0CE',
}}>
<ActivityIndicator animating size="large" />
</View>
);
};
render() {
return (
<View style={styles.SearchContatiner}>
<View style={styles.Search}>
<View style={styles.ImageIcon}>
<Image
style={styles.Image}
resizeMode="contain"
source={require('../images/sokbla.png')}
/>
</View>
<View style={styles.InputBox}>
<TextInput
style={styles.InputText}
onChangeText={text => this.setState({ query: text })}
placeholder={'Search for ' + this.props.Title}
value={this.state.query}
/>
</View>
<TouchableOpacity
onPress={() => alert(this.props.selectedOptions)}
style={styles.KryssIcon}>
<Image
style={styles.ImageKryss}
resizeMode="contain"
source={require('../images/kryssbla.png')}
/>
</TouchableOpacity>
</View>
<View style={styles.Lista}>
<FlatList
style={styles.Flatlist}
data={this.state.data}
renderItem={this.renderRow}
keyExtractor={(item, index) => index.toString()}
ItemSeparatorComponent={this.renderSeparator}
ListFooterComponent={this.renderFooter}
onRefresh={this.handleRefresh}
refreshing={this.state.refreshing}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={0.5}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
width: '20%',
justifyContent: 'center',
alignItems: 'center',
},
buttonGray: {
width: 25,
height: 25,
borderRadius: 12.5,
backgroundColor: 'gray',
},
buttonOrange: {
width: 25,
height: 25,
borderRadius: 12.5,
backgroundColor: 'orange',
},
Lista: {
marginTop: 20,
},
Flatlist: {
width: '100%',
height: 300,
},
ListContainer: {
flexDirection: 'row',
width: '100%',
height: 40,
},
Text: {
marginLeft: '10%',
width: '70%',
justifyContent: 'center',
},
SearchContatiner: {},
Search: {
width: '100%',
height: 60,
backgroundColor: 'rgb(240,240,240)',
flexDirection: 'row',
},
Image: {
width: 23,
height: 33,
},
ImageIcon: {
justifyContent: 'center',
width: '15%',
alignItems: 'center',
},
InputBox: {
width: '70%',
justifyContent: 'center',
},
InputText: {
paddingLeft: 20,
width: '100%',
height: 50,
fontSize: 20,
},
KryssIcon: {
justifyContent: 'center',
width: '15%',
alignItems: 'center',
},
ImageKryss: {
width: 18,
height: 28,
},
});
const mapStateToProps = state => {
return {
selectedOptions: state.filter.selectedOptions,
};
};
const mapDispatchToProps = dispatch => {
return {
onSelectOptions: name => dispatch(selectOptions(name)),
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(Search);
这是我的行动
import { OPTIONS_SELECT } from './actionTypes';
export const selectOptions = name => {
return {
type: OPTIONS_SELECT,
selectedOptions: name,
};
};
还有我的减速机
import {
OPTIONS_SELECT,
} from '../actions/actionTypes';
const initialState = {
selectedOptions:[],
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case OPTIONS_SELECT:
return {
...state,
selectedOptions: [...state.selectedOptions, action.selectedOptions],
};
default:
return state;
}
};
export default reducer;
解决方案
缺少组件的extraData
属性:FlatList
通过将 extraData={this.state} 传递给 FlatList,我们确保 FlatList 本身会在 state.selected 更改时重新渲染。如果不设置这个 prop,FlatList 将不知道它需要重新渲染任何项目,因为它也是一个 PureComponent,并且 prop 比较不会显示任何更改。
链接到文档:https ://facebook.github.io/react-native/docs/flatlist
此属性FlatList
在传递的对象更新时更新。在您的情况下,您需要通过:
extraData={this.props.selectedOptions}
这是您的零食的工作演示。
推荐阅读
- javascript - 为什么我尝试上传图片时出现错误
- javascript - Three.js:更改网格颜色导致只有 1 个面受到更改的影响
- python - MODBUS RTU 命令的语法
- javascript - 纯javascript表格行分页
- matlab - 使用matlab中的fprinf函数改变电源电压和电流制作GUI
- python - Django postgres django.db.utils.OperationalError 通过从 Git Repo 运行
- macos - 适用于 macOS 的云消息传递 (Flutter) 未收到消息
- java - Java浮点格式问题
- asp.net - ASP .NET 5.0 React 与 Docker 无法启动“npm”
- highcharts - Highcharts:在 styledMode 开启时在线条系列上设置笔画宽度无效