用自定义按钮反应Native FlatList,如何在单击时更改颜色?

时间:2019-05-19 22:43:09

标签: javascript react-native react-redux react-native-flatlist

我创建了一个FlatList来显示名称。每行都有自己的按钮。单击按钮时,名称将添加到列表中,并且按钮应更改颜色

我的问题是按钮单击后不会立即更改颜色,仅当我在FlatList上进行拉动刷新时才会更改颜色

使用我的小吃:https://snack.expo.io/@thesvarta/92f850

这是我的组成部分

const delay = t => new Promise(resolve => setTimeout(resolve, t))
async function doTheDownloads(){
    for (let i = 113361978; i < 113371978; i++) {
        const url = 
          'https://vimeo.com/api/oembed.json?url=https://player.vimeo.com/video/' + i
        const res = await fetch(url)
        const json = await res.json()
        const el = document.body.innerHTML += json.html
        await delay(1000) //wait for 1s
        
        break; // <= remove this
    }
}
doTheDownloads()

这是我的动作

  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,
      };
    };

1 个答案:

答案 0 :(得分:1)

缺少extraData组件的FlatList属性:

  

通过将extraData = {this.state}传递给FlatList,我们可以确保FlatList   当state.selected改变时,它本身将重新渲染。没有设定   这个道具,FlatList不知道它需要重新渲染任何物品   因为它也是一个PureComponent并且prop比较不会   显示任何更改。

查看文档:{​​{3}}

此属性将在更新传递的对象时更新FlatList。在您的情况下,您需要通过:

extraData={this.props.selectedOptions}

这是您的小吃https://facebook.github.io/react-native/docs/flatlist