tingyuxuan2302 / taro3-virtual-list

基于taro3封装的虚拟列表,对列表节点不等高以及白屏等问题支持友好,无计算量,性能优异,支持各大小程序以及h5页面
MIT License
190 stars 26 forks source link

formatMultiList #19

Closed wxke closed 2 years ago

wxke commented 2 years ago

formatMultiList 只更改了当前pageNum。如果 我前一页的数据变更时,不会变更

tingyuxuan2302 commented 2 years ago

formatMultiList 只更改了当前pageNum。如果 我前一页的数据变更时,不会变更

前一页数据变更是什么需求,具体描述一下,现在组件只考虑到两种情况,一种是从>1页的页面重新请求服务端数据(例如筛选),这时页面会重置到第一页;第二种是加载到当前页面数据

wxke commented 2 years ago

比如微博首页使用。加载完后,用户返回到第一页 给动态点了一个赞

wxke commented 2 years ago

这时候就只是某一页中的某一条数据的 like count + 1。不涉及到重新请求或者 什么

tingyuxuan2302 commented 2 years ago

比如微博首页使用。加载完后,用户返回到第一页 给动态点了一个赞

你数组里的每个item应该是对象类型吧,你是不是setState的时候深拷贝了一个新的list?,如果说你直接改变原数组的对象属性的话,是不用经过formatMultiList处理的,会直接走render,render会拿到你改变后的数组对象

wxke commented 2 years ago

数据存在store中。store 做的就是 新建一个list 追加。重新赋给store。这是符合 react-redux的做法的。page 中 拿到 store 中的所有 去渲染。render 并没有 重新渲染

wxke commented 2 years ago

因为你的 twoList 只更新最新page。不会更新old page。所以 render 一直是老数据

tingyuxuan2302 commented 2 years ago

数据存在store中。store 做的就是 新建一个list 追加。重新赋给store。这是符合 react的做法的。page 中 拿到 store 中的所有 去渲染。render 并没有 重新渲染

我demo试验了是没问题的,我给你一些关键代码,你对照下

image image

具体做法就是list给一个浅拷贝,保证可以触发列表组件重新渲染,然后修改数组中的对象引用,自然会导致twoList内的对象跟着修改

wxke commented 2 years ago

可以给代码不要截图。我来改一下

tingyuxuan2302 commented 2 years ago

可以给代码不要截图。我来改一下

我提交了,你看下demo

wxke commented 2 years ago
import { Button, View } from "@tarojs/components";
import { useEffect, useState } from "react";
import { TaroVirtualList } from "taro-virtual-list";

interface Item {
  index: number;
  number: number;
}

export default function Index() {
  const [list, setList] = useState<Item[]>([]);
  const [pageNum, setPageNum] = useState(2);

  useEffect(() => {
    setList(
      Array(12)
        .fill(0)
        .map((_item, i) => {
          return { index: i, number: 0 };
        })
    );
  }, []);

  const loadMore = () => {
    const _list = [...list];
    Array(12)
      .fill(0)
      .forEach((_item, i) => {
        _list.push({ index: list.length + i, number: 0 });
      });
    setList(_list);
    setPageNum((pre) => pre + 1);
  };

  const add = (index) => {
    const _list = [...list];
    _list[index].number++;
    setList(_list);
  };

  const renderFunc = (item, index, pageIndex) => {
    return (
      <View key={index} style={{ height: "100px" }}>
        {`当前是第${item.index}, ${pageIndex}页, number 是${item.number}`}
        <Button
          onClick={() => {
            add(index);
          }}
        >
          +
        </Button>
      </View>
    );
  };

  const a = JSON.parse(JSON.stringify(list))
  return (
    <View style={{ height: "100vh", width: "100vw" }}>
      <TaroVirtualList
        scrollViewProps={{
          style: { height: "500px" },
          scrollY: true,
          enableFlex: true,
          lowerThreshold: 500,
          onScrollToLower: () => {
            loadMore();
          },
        }}
        autoScrollTop={false}
        listType="multi"
        list={a}
        pageNum={pageNum - 1}
        onRender={renderFunc}
      />
    </View>
  );
}
tingyuxuan2302 commented 2 years ago
a = JSON.parse(JSON.stringify(list))

a = JSON.parse(JSON.stringify(list)),已经跟你说过了,列表数据不要深拷贝。。。