React useEffect和useState返回数字而不是对象

时间:2019-11-14 14:02:49

标签: javascript arrays angularjs reactjs infinite-scroll

我已经为这个问题解决了2天,我正在尝试实现连续的垂直文本滚动,但是由于某些我不知道的原因,react返回一个数字而不是我的数组对象(在我记录了输出之后以查看我的代码出了什么问题)(在第二次迭代中)(因为该数组每隔一段时间就会不断更新)。作为记录,这最初是在Angular JS应用程序中实现的,但是我试图将其转换为与useEffect()useState()反应以更新数组中的更改。

以下是我到目前为止所做的:

const Skills = () => {
  let skillWrap = useRef();

  let [activeSkills, setActiveSkills] = useState([]);
  console.log(activeSkills);
    console.log(typeof activeSkills);

  let sMax = totalSkills.length - 1; // 0 -> 19

  let activeStart = Math.floor(Math.random() * (sMax + 1));
  let activeEnd = activeStart === 0 ? sMax : activeStart - 1;

  for (let e = activeStart; e <= sMax; e++) {
    setActiveSkills(activeSkills.push(totalSkills[e]));
  }

  if (activeStart !== 0) {
    for (let s = 0; s <= activeEnd; s++) {
      setActiveSkills(activeSkills.push(totalSkills[s]));
    }
  }

  let scrollDis = 0,
    scrollingDown = false,
    scrollingUp = false,
    scrollingDownSelf = false,
    scrollingUpSelf = false,
    scrollCatchInterval = 40,
    scrollDirection = "up",
    hasScrolledRecently = false;

  const wheelEventHandler = e => {
    let skillFocused = skillWrap.current.childNodes[19];

    skillFocused.classList.remove("active");

    function animateScroll(scrollDis, callback) {
      let curLeftTop = scrollDis * 8,
        curLeftFinal = scrollDis * 4;
      tween(skillWrap.current, -curLeftFinal, curLeftTop, 1, callback);
    }

    function scrollUp() {
      setTimeout(() => {
        for (let su = 0; su < scrollDis; su++) {
          activeEnd--;
          activeStart--;
          if (activeEnd < 0) activeEnd = 19;
          if (activeStart < 0) activeStart = 19;

          /*setActiveSkills(activeSkills.unshift(totalSkills[activeStart]));
                    setActiveSkills(activeSkills.pop());*/
          activeSkills.unshift(totalSkills[activeStart]);
          activeSkills.pop();
        }
        skillFocused.classList.add("active");
        skillWrap.current.style.transform = "none";
        scrollDis = 0;
        scrollingUp = false;
        scrollingUpSelf = false;
        if (e.deltaZ === 0) {
          setTimeout(() => {
            hasScrolledRecently = false;
          }, 3000);
        }
      }, 0);
    }

    function scrollDown() {
      setTimeout(() => {
        for (let sd = 0; sd < Math.abs(scrollDis); sd++) {
          activeEnd++;
          activeStart++;
          if (activeEnd > 19) activeEnd = 0;
          if (activeStart > 19) activeStart = 0;

          /*setActiveSkills(activeSkills.push(totalSkills[activeEnd]));
                    setActiveSkills(activeSkills.shift());*/
          activeSkills.push(totalSkills[activeEnd]);
          activeSkills.shift();
        }
        skillFocused.classList.add("active");
        skillWrap.style.transform = "none";
        scrollDis = 0;
        scrollingDown = false;
        scrollingDownSelf = false;
        if (e.deltaZ === 0) {
          setTimeout(() => {
            hasScrolledRecently = false;
          }, 3000);
        }
      }, 0);
    }

    if (
      (e.deltaY === 100 || e.deltaY === 3) &&
      !scrollingUp &&
      !scrollingDownSelf
    ) {
      // (scroll down) add skill to bottom & remove skill from top
      scrollDirection = "down";
      scrollDis--;
      scrollingDown = true;
      if (e.deltaZ === 0) hasScrolledRecently = true;
      let scd = scrollDis;
      setTimeout(() => {
        if (scrollDis === scd) {
          if (scrollDis < -6) scrollDis = -6;
          scrollingDownSelf = true;
          animateScroll(scrollDis, scrollDown);
        }
      }, scrollCatchInterval);
    } else if (
      (e.deltaY === -100 || e.deltaY === -3) &&
      !scrollingDown &&
      !scrollingUpSelf
    ) {
      // (scroll up) add skill to top & remove skill from bottom
      scrollDirection = "up";
      scrollDis++;
      scrollingUp = true;
      if (e.deltaZ === 0) hasScrolledRecently = true;
      let scu = scrollDis;
      setTimeout(() => {
        if (scrollDis === scu) {
          if (scrollDis > 5) scrollDis = 5;
          scrollingUpSelf = true;
          animateScroll(scrollDis, scrollUp);
        }
      }, scrollCatchInterval);
    }
  };

  function tween(o, x, y, durationSecs, onComplete) {
    let fps = 30,
      count = 0,
      stopAt = fps * durationSecs,
      easef = Quad_easeInOut;
    let f = function() {
      count++;
      if (count >= stopAt) {
        tween_stop(o);
        if (onComplete) onComplete();
      } else {
        tween_setProperty(
          o,
          easef(count, 0, x, stopAt),
          easef(count, 0, y, stopAt)
        );
      }
    };
    clearInterval(o._tween_int);
    o._tween_int = setInterval(f, (durationSecs * 1000) / fps);
  }

  function tween_stop(o) {
    clearInterval(o._tween_int);
  }

  function tween_setProperty(o, x, y) {
    o.style.cssText += ";transform:translate3d(" + x + "vw," + y + "vh,0);";
  }

  function Quad_easeInOut(t, b, c, d) {
    if ((t /= d / 2) < 1) return (c / 2) * t * t * t * t + b;
    return (-c / 2) * ((t -= 2) * t * t * t - 2) + b;
  }

  useEffect(() => {
    /*console.log(activeSkills);*/

    setTimeout(() => {
      skillWrap.current.childNodes[19].classList.add("active");
    }, 2000);

    window.addEventListener("wheel", wheelEventHandler);

    function constantScroll() {
      // prevents scrolling while changing views
      setTimeout(function() {
        // emulate scrolling of the skill list
        let scrollEvent = new WheelEvent("wheel", {
          deltaY: scrollDirection === "up" ? -100 : 100,
          deltaZ: 1 // used to differentiate between user scroll / programmatic scroll
        });

        if (!hasScrolledRecently) {
          // 3 scroll events are dispatched to mirror scrolling of 3 skills
          for (let r = 0; r < 3; r++) {
            window.dispatchEvent(scrollEvent);
          }
        }
        constantScroll();
      }, 3000);
    }

    // wait 3 seconds before issuing first scroll
    setTimeout(function() {
      constantScroll();
    }, 2000);

    return () => {
      window.removeEventListener("wheel", wheelEventHandler);
      console.log("Skills Component will unmount");
    };
  }, [activeSkills]);

  return (
    <div>
      <div className="view skills active active-f">
        <div className="header-container skills">
          <div className="header-title-wrap">
            <div className="cover" />
            <h1 className="header big first">My</h1>
            <h1 className="header big last">Skillsset</h1>
          </div>
          <div className="header-info-wrap">
            <div className="header-content-body skill-one">
              <div className="line-left" />
              <p className="header body about-one">
                The core of my skill set largely surrounds the MERN{" "}
                <strong>stack</strong>, to achieve both a clear and dynamic user
                experience. I also have some experience with mobile integration
                (Android and iOS). Strengthening my grasp of the mobile app
                development space is one of my primary goals for the near
                future.
              </p>
            </div>
          </div>
        </div>
        <div className="skill-container active active-f">
          <div className="skill-wrap">hey</div>
        </div>
      </div>
      <div className="skill-container active-f active">
        <div ref={skillWrap} className="skill-wrap">
          {console.log(activeSkills)}
          {activeSkills.map((skill, i) => (
            <div key={i} className="skill">
              {skill}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

下面是https://codesandbox.io/页面,查看我到目前为止所做的事情,以及我正在尝试用React实现的Angular JS实现的链接。

我的React实现(来自技能路线):https://codesandbox.io/s/shy-http-jlrle
原始Angular实施(技能路线):https://codesandbox.io/s/github/eazylaykzy/portfolio-ex

我真的很感激能帮助我使它生效。

1 个答案:

答案 0 :(得分:0)

就像我的评论中提到的那样抽象第一部分,您可以编写自己的钩子并按原样使用

import React, { useMemo } from 'react';

// How to shuffle an array
// https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
function shuffle(array) {
  const newArray = [...array];
  for (let i = newArray.length - 1; i > 0; i -= 1) {
    const j = Math.floor(Math.random() * (i + 1));
    [newArray[i], newArray[j]] = [newArray[j], newArray[i]];
  }
  return newArray;
}

function useActiveSkills(skills) {
  return useMemo(() => shuffle(skills), [skills]);
}

function Component() {
  const activeSkills = useActiveSkills();

  return (
    <>
      {activeSkills.map((skill) => (
        <p>{skill.name}</p>
      ))}
    </>
  );
}