React Native Hooks如何在无状态组件中使用Hook有条件地更新Flatlist数据?

问题描述

现在,在继续之前,我确实知道在无状态组件中使用Hook的基本原理

  1. 仅在顶层调用钩子:请勿在循环,条件或嵌套函数内部调用钩子
  2. 仅来自React Functions的调用挂钩:不仅可以从任何常规的javascript函数中调用,而且还可以从React函数组件中进行调用。

有了这种方式,这就是我想要实现的目标:

  • 我有一个目录页面,其中包含一个平面列表。它显示从目录api获取的所有产品列表。
  • 我在Flatlist上方有一个Binary Option Switch,可使用公用密钥启用/禁用数组中的项目分组。
  • 我希望单位列表根据是否启用分组功能(即条件渲染项)动态更改渲染项。

顺便说一句,让我们看一下我的代码。下面是我的用例的完整代码:

import React,{ useState,useEffect } from "react";
------ /** imports from other libraries **/ ------

export default function Catalogue({ navigation }){
  const url = 'http://url to the api'
  const token = 'authentication token for the api'
  
  //products array will be displayed using Flatlist & groupby filter will be applied
  const [products,setProducts] = useState([]);
  
  //catalogue array will hold all the original data fetched from the api. 
  //Is used to reset products with original data if needed
  const [catalogue,setCatalogue] = useState([]);

  const [groupBy,setGroupBy] = useState("model");
  const onChangeGroup = (value) => setGroupBy(value);

  //Function to fetch data from the api
  useEffect(() => {
    async function getCatalogue() {
      const response = await Axios.get(url,{
        headers: { Authorization: token },});
      if (response.data.tokenExpired) {
        alert("Session has expired");
        return;
      }
      setProducts(response.data.data);
      setCatalogue(response.data.data);
    }
    getCatalogue();
  },[]);

  useEffect(() => {
    console.log("products updated",products);
  },[products]);
  
  //Call the handle function when state is changed by the switch
  useEffect(() => {
    console.log("groupby updated from useEffect",groupBy);
    handleGroupBy();
  },[groupBy]);
  
  //Function which returns either original data or grouped items array
  const handleGroupBy = async () => {
    console.log("function called");
    if (groupBy == "model") {
      await setProducts(catalogue); //return original api data
    } else if (groupBy == "manufactor") {
      console.log("entered logic");
      //Logic for grouping items in an array
      const key = "designNumber";
      const groupedList = await catalogue.reduce(
        (hash,object) => ({
          ...hash,[object[key]]: (hash[object[key]] || []).concat(object),}),{}
      );
      console.log("grouped array",groupedList);
      setProducts(groupedList);
    }
  };
  
  return(
    <View>
      <DualSwitch
        initialValue={0}
        onPress{(value) => onChangeGroup(value)}
        options={[
          { label: "Model ",value: "model" },{ label: "Manufacturer ",value: "manufactor" },]}
      />
      <FlatList
        key={orientation}
        numColumns={isPhone ? phoneColumns : tabletColumns}
        style={styles.flatList}
        columnWrapperStyle={styles.flatlistColums}
        data={products}
        extraData={groupBy}
        keyExtractor={(item) =>
          groupBy == "model" ? item.model : item.manufacturer
        }
        renderItem={({ item }) => 
          groupBy == "model" ? (
            <ProductCatalogueItem item={item} navigation={navigation} />
          ) : (
            <GroupedItem item={item} navigation={navigation} />
          )
        }
      />
    <View/>
  )
}

好吧,在经历了之后,一切在逻辑上似乎都是正确的,对吧?那怎么了?

这里是React Hooks的问题。在通过这种方法执行useCase之后,这是我的控制台日志的样子:

  1. 组件负载
  2. 数据是从api中获取的
  3. 单位列表已加载
  4. 我轻弹了从模型到制造商的切换

这是控制台日志

//1. Component is mounted
products updated Array []

groupby updated from useEffect modal

function called

//2. data is fetched from the api
products updated Array []

products updated Array [
  //whole list of objects from the api
]

//3. Flatlist gets loaded
//4. I flick the switch from Model to Manufacturer
groupby updated from useEffect manufactor

/**App Crashes right here **/

function called

entered logic

grouped array Object {
  "key 1": Array [
    Object {
      item 1
    },Object {
      item 4
    },Object {
      item 5
    },],"key 2": Array [
    Object {
      item 2
    },Object {
      item 3
    },]
}

products updated Object {
  "key 1": Array [
    Object {
      item 1
    },]
}

//This here is the MOST Bizzare behaviour. the useEffect hooks are called again! like why?
products updated Array[]

groupby updated from useEffect modal

function called

应用崩溃后出现的错误是:

Crash Message

所以请帮助我,我不知道为什么该应用程序崩溃了。我只在if条件中称为状态变量的setter函数。哪些afaik不被视为钩子,并且不违反React Hooks的2条基本原则。有什么想法可能会出错吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...