【问题标题】:How do you re-render Flatlist when value of dropdown list changes?当下拉列表的值发生变化时,如何重新渲染 Flatlist?
【发布时间】:2020-10-16 16:25:13
【问题描述】:

我正在从状态变量 this.state.dataSource 中的 Componentdidmount 中的数据库中获取一个数组

componentDidMount(){

    fetch("http://docbook.orgfree.com/home.php", {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        "auth-token": "my token",
      },
    })
      .then((response) => response.json())
      .then((responseJson) => {
        this.setState({
          isLoading: false,
          dataSource: responseJson, 

        });
        if (responseJson) {
          Alert.alert("Id is" + JSON.stringify(responseJson)); 
        // this.state.dataSource = this.state.dataSource.filter(x => x.Tag === this.state.text);
        // console.log(this.state.dataSource[0])
         
        } else if (responseJson.error) {
          Alert.alert(responseJson.error);
        }
      })

      .catch((error) => {
        console.error(error);
      });

    
}

this.state.Datasource 包含一个数组,如:

[ { 描述:“kjs”, 标签:“海滩”, 名称:“nkslk”, 地点:“kdlk”, 图片:“kgmls” }, { 描述:“knsldk”, 标签:“俱乐部”, 名称:“nklf”, 地点:“dlk”, 图片:“nkxn” }, ]

我有一个下拉列表,其中包含我的数据库中不同标签的值,例如 海滩、俱乐部、寺庙、堡垒等

我只想在我的平面列表中呈现标签与我的数组中的标签匹配的那些项目,并且当下拉值更改时我想将我的平面列表重新呈现为具有新标签的数组元素

我的完整源码:

import React, { Component } from "react";
import { Dropdown } from 'react-native-material-dropdown';
import { Button, View, Text, StyleSheet, Image ,Alert,FlatList} from "react- 
native";
class explore extends Component {
    constructor(props) {
       super(props);
        this.state = {
        tag: '',
       isLoading:true,
       dataSource:[]
    };
}

componentDidMount(){

    fetch("http://docbook.orgfree.com/home.php", {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        "auth-token": "my token",
      },
    })
      .then((response) => response.json())
      .then((responseJson) => {
        this.setState({
          isLoading: false,
          dataSource: responseJson, 

        });
        if (responseJson) {
          // Alert.alert("Id is" + JSON.stringify(responseJson)); 
          console.log(this.state.dataSource)
         
        } else if (responseJson.error) {
          // Alert.alert(responseJson.error);
        }
      })

      .catch((error) => {
        console.error(error);
      });

    
}

render() {
    const { dataSource, tag } = this.state;

    const tagFilter = item => {
          if (tag) {
            return item.tag === tag;
          }
          return true;
    }
    let data = [{
      value: 'Church',
    }, {
      value: 'Beach',
    }, {
      value: 'Temple',
    },{
      value:'Waterfall' 
    },
    {
      value:'Town'
    }];
    
return (    
      <View>
        <Dropdown
            label='TAG'
            data={data}
            onChangeText={tag => this.setState({ tag })}
        />
        <FlatList
          data={dataSource.filter(tagFilter)}
          ItemSeparatorComponent={this.FlatListItemSeparator}
          renderItem={({ item }) => (
            <View >
              <Text >{item.name}</Text>
              <Text >#{item.Tag}</Text>

             
            </View>
          )}
          keyExatractor={({ name }) => name}
        />


      </View>

);
}
}
export default explore;

【问题讨论】:

    标签: javascript reactjs react-native expo react-native-flatlist


    【解决方案1】:

    保存标签以在状态中过滤并简单地过滤您的数据源内联与下拉组件的 onChange 回调。下面从状态中解构tag 和dataSource,并定义一个过滤函数用作array::filter 回调。如果tag 为真,则在标签匹配时应用过滤器,否则返回真以允许通过项目,即未过滤。

    this.state = {
      text: 'Temple',
      isLoading: true,
      dataSource: [], // <-- provide defined initial state
      tag: '', // <-- tag
    };
    
    ...
    
    render() {
      let data = [{
          value: 'Church',
        }, {
          value: 'Beach',
        }, {
          value: 'Temple',
      }];
    
      const { dataSource, tag } = this.state; // <-- destructure
    
      const tagFilter = item => { // <-- filter callback
        if (tag) {
          return item.tag.toLowerCase() === tag.toLowerCase(); // <-- compare using lowercase!
        }
        return true;
      }
    
      return (    
        <View>
          <Dropdown
            label='TAG'
            data={data}
            onChangeText={tag => this.setState({ tag })} // <-- save tag to state
          />
          <FlatList
            data={dataSource.filter(tagFilter)} // <-- filter data
            ItemSeparatorComponent={this.FlatListItemSeparator}
            renderItem={({ item }) => (
              <View >
                <Text >{item.name}</Text>
                <Text >#{item.Tag}</Text>
              </View>
            )}
          />
        </View>
      );
    }
    

    【讨论】:

    • TypeError:undefined is not an object (evalating dataSource.filter)
    • @Akashkunwar 你是否从状态对象中解构了dataSource?我会更新答案,以便更清楚地了解更改的去向。
    • @Akashkunwar 已更新。附加说明,由于底层数据正在更改,并且FlatList 默认使用索引,如果数据没有key 属性或者您没有指定keyExtractor,您可能会遇到渲染问题,只是一个警告。希望这更清楚一点。
    • 我已经根据您所做的更改更新了我的代码,但我仍然收到 TypeError: undefined is not an object (evalating dataSource.filter) 而且我认为没有任何渲染问题因为它在不同的活动中渲染得很好。
    • 我也更新了我的问题,如果您可以查看更新后的代码,这将非常有帮助
    猜你喜欢
    • 1970-01-01
    • 2021-02-22
    • 2017-05-06
    • 2022-06-30
    • 2017-10-18
    • 1970-01-01
    • 2020-04-29
    • 2021-12-28
    • 2022-01-24
    相关资源
    最近更新 更多