Как избежать создания полых пружин в реактивной пружине - PullRequest
0 голосов
/ 07 апреля 2020

Я создаю «поддельный» компонент просмотра стека, у меня есть массив идентификаторов, где каждый идентификатор загружает сложные объекты в карту, поэтому мне нужно предварительно загрузить 2 карты и затем при каждом добавлении клика добавлять новая карта, чтобы я мог получить более плавный опыт вставки.

Я не использую useTransition, потому что каждая карта монтируется лениво, а впечатление не гладкое (из-за времени монтирования).

Я получил то, что хотел, однако я создаю потраченные впустую пружины (см. Журнал консоли), это был единственный способ создать новую пружину для каждой добавленной карты, предыдущая весна «запоминает» текущую позицию и я не могу их повторно использовать

есть ли лучший способ добиться этого?

codesandbox: https://codesandbox.io/s/jolly-stonebraker-fjd19?file= / src / App.jsx

import React, { useState, useEffect } from "react";
import { useSpring, animated, useSprings } from "react-spring";
import "./styles.css";
import Card from "./Card";

let data = [];
for (let i = 0; i < 50; i++) {
  data.push(i);
}

export default function App() {
  const [currentData, setCurrentData] = useState([data[0], data[1]]);
  const [currentIndex, setCurrentIndex] = useState(0);

  const [springs, set] = useSprings(currentData.length, idx => {
    const isLast = idx === currentData.length - 1;
    console.log("init uses spring");
    return {
      from: { x: isLast ? 300 : 0 },
      onRest: () => {
        console.log("on reset");
        setCurrentIndex(currentIndex + 1);
        const newArr = [...currentData];
        newArr.push(data[currentIndex + 2]);
        newArr[currentIndex] = null;
        setCurrentData(newArr);
      }
    };
  });

  // const springs = [goAwayProps, slideInProps];

  useEffect(() => {
    console.log("mount");
  }, []);

  const handleNext = () => {
    // setCurrentData([data[currentIndex + 1], data[currentIndex + 2]]);
    set(idx => {
      const isLast = idx === currentData.length - 1;
      return {
        to: async next => {
          await next({
            x: isLast ? 0 : -80
          });
        }
      };
    });
  };

  console.log(currentData);
  return (
    <div className="App">
      <button onClick={handleNext}>next</button>
      <div className="container">
        {currentData.map((d, i) => {
          if (d === null) return null;
          const { x } = springs[i];
          return (
            <animated.div
              style={{
                transform: x.interpolate(x => `translate3d(${x}px,0,0)`)
              }}
            >
              <Card>{d}</Card>
            </animated.div>
          );
        })}
      </div>
    </div>
  );
}
...