【问题标题】:Problem filtering and rendering an array asynchronously in React native在 React Native 中异步过滤和渲染数组的问题
【发布时间】:2021-11-26 22:03:06
【问题描述】:

我正在尝试在具有属性Id 的一组对象中应用过滤器,以获取以输入文本开头的项目列表。 我在数组中只有两个元素,但是 如果我得到相同的两个元素(呈现为列表)。

我需要做什么来修复函数SearchFilter中的过滤器逻辑?

import React, { useEffect, useState } from "react"
import {useSelector} from 'react-redux'
import {View, Item, Text, Icon, Input, List, ListItem, Left, Thumbnail, Spinner} from 'native-base'

const SearchModal =(props:any)=>{
  const sessionsCata = useSelector((state)=> state.sessionsCata.sessions)
  const [itemsFiltered, setItemsFiltered] = useState([]) 
  const [showSpinner, setShowSpinner] =useState(false)

  //filter the array objects
  async function SearchFilter(params:string) {
    setShowSpinner(true)
    if(sessionsCata && sessionsCata.length>0){
        let result = await sessionsCata.filter(async x=> x.Id.startsWith(params) )
        if(result)
            setItemsFiltered(result)
    }            
    await Sleep(500) //function with Promise-setTimeout
    setShowSpinner(false)
  }

  return(
        <View style={StylesSearch.containerBar} >
            <Item rounded style={StylesSearch.searchBar}>
                <Input placeholder='Id...' onChangeText={async (text) => await SearchFilter(text)} />
            </Item>
        </View>
        <View> 
            { showSpinner ? <Spinner color='grey'/> :
                itemsFiltered && itemsFiltered.length>0 ? (
                    <List>
                    {
                        itemsFiltered.map(item=>(
                            <ListItem avatar key={item.id}>
                                <Body>
                                    <Text>{item.id}</Text>
                                </Body>
                            </ListItem>
                        ))
                    }                      
                    </List> 
                ): <Text>Not items filtered...</Text>
            }                                   
            </View>
   )
}

【问题讨论】:

  • 我不明白这个I have only two elements in the array but ever I get the same two elements (render as a list) 是什么意思。你的意思是你永远不会得到这两个元素?
  • 当我在输入中输入任何值时,渲染所有的项目

标签: javascript react-native asynchronous filter


【解决方案1】:

您不需要在过滤器上使用 async/await。它不是异步的。此外,由于 itemsFiltered 是确定性的(基于 sessionCata 状态),它不应该是它自己的状态。

const [prefix, setPrefix] = useState("");

const itemsFiltered = sessionsCata.filter(x => x.Id.startsWith(prefix));

// Then
<Input onChangeText={setPrefix} />

【讨论】:

  • 过滤的items不是可赋值的,只能使用setItemsFiltered
  • 是的,删除 const [itemsFiltered, setItemsFiltered] = useState([]) 并改用 const itemsFiltered。这就是我的意思,它不应该是它自己的状态。这是确定性的。 kentcdodds.com/blog/dont-sync-state-derive-it
  • 错误 undefined is not an object (evalating 'x.Id.startsWith')
  • undefined 因为 "useSelector((state)=> state.sessionsCata.sessions)" 没有在 itemsFiltered 定义之前填充变量
  • redux 中应该有一些初始状态,这样就不会发生这种情况。你也可以写(sessionsCata || []).filter(x =&gt; x?.Id?.startsWith(prefix)),它永远不会抛出类型错误。
【解决方案2】:

改变:

if(sessionsCata && sessionsCata.length>0){
    let result = await sessionsCata.filter(async x=> x.Id.startsWith(params) )
    if(result)
    {
      if(JSON.stringify(itemsFiltered).includes(JSON.stringify(result)))
      return;
      setItemsFiltered(result)
    }        
} 

【讨论】:

  • 不工作,渲染崩溃
【解决方案3】:

我终于明白了。错误是属性 ID -> id。

我从过滤器中退出异步,将验证放入参数中。

async function SearchFilter(params:string) {
    setShowSpinner(true)
    await Sleep(500)
    setShowSpinner(false)

    if(sessionsCata && sessionsCata.length>0 && params.length>0){
        let result = sessionsCata.filter( x=> x.id.startsWith(params) )
        if(result)
            setItemsFiltered(result)
    }            
}

更改输入:

<Input placeholder='Id...' onChangeText={ (text) =>  SearchFilter(text)} />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    相关资源
    最近更新 更多