簡體   English   中英

React Ref 沒有更新 CSS

[英]React Ref is not updating the CSS

需要更新我的 imgTrack 的 transform translate imgTrack ,但不能直接在 React 中更改它,嘗試了多種方法,但是 transform 屬性永遠不會更新(或者看起來如此)。

為此,我創建了一個 function 來測量按下鼠標時移動的距離,將其轉換為百分比,然后嘗試使用該百分比來更新變換值。

您可以在此處查看已實施的沙箱

這是相同的基本代碼

const [mouseDownAt, setMouseDownAt] = useState(0);
    const [prevPercentage, setPrevPercentage] = useState(0);
    const [percentage, setPercentage] = useState(0);
    const imgTrackRef = useRef(null);

    useEffect(() => {
        const track = imgTrackRef.current;
        window.onmousedown = function (e) {
            setMouseDownAt(e.clientX);
        };
        window.onmousemove = function (e) {
            if (mouseDownAt === 0) return;
            const mouseDelta = mouseDownAt - e.clientX,
            maxDelta = window.innerWidth / 2;
            const percentage = (mouseDelta / maxDelta) * -100,
                nextPercentage = prevPercentage + percentage;
            setPercentage(nextPercentage);
            track.style.transform = `translateX(${nextPercentage}%, -50%)`
        };
        window.onmouseup = function () {
            setMouseDownAt(0);
            setPrevPercentage(percentage);
        };
        console.log("mouseDownAt: ", mouseDownAt);
        console.log("prevPercentage: ", prevPercentage);
        console.log("percentage: ", percentage);
    }, [ mouseDownAt, prevPercentage, percentage]);

至於渲染部分

<div id="imgTrack" ref = {imgTrackRef}>
   <img className='image' src="" draggable="false" />
   <img className='image' src="" draggable="false" />
   <img className='image' src="" draggable="false" />
</div>

我嘗試將值存儲在狀態中,然后將其與 ref 一起使用,但都沒有用。 任何幫助,將不勝感激!

您的樣式沒有更新,因為您的onmousemove事件偵聽器 function always0作為所有 state 變量的值。 發生這種情況是由於javascript中的關閉。 事件偵聽器 function 是在組件首次安裝后創建的,此時所有 state 變量值為0

要獲取所有 state 變量的updated value ,您需要使用useRef() 這個想法是為each state 變量創建a ref ,並在每次重新渲染時更新ref's current值。 Refs中的引用是mutable的,所以值會改變但reference不會改變。 因此,您將能夠在DOM event listener器中獲取updated后的值。

解決方案

const [mouseDownAt, setMouseDownAt] = useState(0);
const [prevPercentage, setPrevPercentage] = useState(0);
const [percentage, setPercentage] = useState(0);
const imgTrackRef = useRef(null);

const mouseDownAtRef = useRef(mouseDownAt);
const prevPercentageRef = useRef(prevPercentage);
const percentageRef = useRef(percentage);

// update the value of the refs each time the
// component rerenders due to state update
mouseDownAtRef.current = mouseDownAt;
prevPercentageRef.current = prevPercentage;
percentageRef.current = percentage;

useEffect(() => {
  const track = imgTrackRef.current;
  window.onmousedown = function (e) {
    setMouseDownAt(e.clientX);
  };
  window.onmousemove = function (e) {
    if (mouseDownAtRef.current === 0) return;
    const mouseDelta = mouseDownAtRef.current - e.clientX,
      maxDelta = window.innerWidth / 2;
    const percentage = (mouseDelta / maxDelta) * -100,
      nextPercentage = prevPercentageRef.current + percentage;
    setPercentage(nextPercentage);
    track.style.transform = `translateX(${nextPercentage}%, -50%)`;
  };
  window.onmouseup = function () {
    setMouseDownAt(0);
    setPrevPercentage(percentage);
  };
}, [mouseDownAt, prevPercentage, percentage]);

為您的代碼沙箱Updated Project.jsx文件

import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, useIsPresent } from "framer-motion";
import "./projects.scss";

function Projects() {
  const isPresent = useIsPresent();
  const container = {
    visible: {
      transition: {
        staggerChildren: 0.1,
        delayChildren: 1
      }
    }
  };

  const [mouseDownAt, setMouseDownAt] = useState(0);
  const [prevPercentage, setPrevPercentage] = useState(0);
  const [percentage, setPercentage] = useState(0);
  const imgTrackRef = useRef(null);

  const mouseDownAtRef = useRef(mouseDownAt);
  const prevPercentageRef = useRef(prevPercentage);
  const percentageRef = useRef(percentage);

  // update the value of the refs each time the
  // component rerenders due to state update
  mouseDownAtRef.current = mouseDownAt;
  prevPercentageRef.current = prevPercentage;
  percentageRef.current = percentage;

  useEffect(() => {
    const track = imgTrackRef.current;
    window.onmousedown = function (e) {
      setMouseDownAt(e.clientX);
      console.log("mousedown: ", e.clientX);
    };
    window.onmousemove = function (e) {
      if (mouseDownAtRef.current === 0) return;
      console.log("mousemove: ", mouseDownAtRef.current);
      const mouseDelta = mouseDownAtRef.current - e.clientX,
        maxDelta = window.innerWidth / 2;
      const percentage = (mouseDelta / maxDelta) * -100,
        nextPercentage = prevPercentageRef.current + percentage;
      setPercentage(nextPercentage);
      track.style.transform = `translateX(${nextPercentage}%, -50%)`;
    };
    window.onmouseup = function () {
      setMouseDownAt(0);
      setPrevPercentage(percentage);
      console.log("mouseup: ", percentage);
    };

    console.log();
  }, [mouseDownAt, prevPercentage, percentage]);

  return (
    <>
      <motion.div
        ref={imgTrackRef}
        className="projectsWrapper"
        initial={{ x: 712 }}
        animate={{ x: 0 }}
        transition={{ duration: 0.7, type: "spring", stiffness: 60 }}
        style={{ overflow: "hidden" }}
      >
        <div
          id="imgTrack"
          style={{ transform: `translate(${-percentage}%, -50%)` }}
        >
          <img
            className="image"
            src="https://images.unsplash.com/photo-1507830940122-38f2fbc6abdd?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=685&q=80"
            alt="Huffman_compressor"
            draggable="false"
          />
          <img
            className="image"
            src="https://images.unsplash.com/photo-1565789623612-5d58a09e0a28?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1326&q=80"
            alt="flavours_of_youth"
            draggable="false"
          />
          <img
            className="image"
            src="https://images.unsplash.com/photo-1601379342258-6f1e994c575c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80"
            alt="savourly"
            draggable="false"
          />
          <img
            className="image"
            src="https://images.unsplash.com/photo-1593873964743-0d8b01c5c09f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80"
            alt="fier_v1"
            draggable="false"
          />
          <img
            className="image"
            src="https://images.unsplash.com/photo-1472851294608-062f824d29cc?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80"
            alt="prodigi"
            draggable="false"
          />
          <img
            className="image"
            src="https://images.unsplash.com/photo-1510146758428-e5e4b17b8b6a?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80"
            alt="teamio"
            draggable="false"
          />
        </div>
      </motion.div>

      <motion.div
        initial={{ scaleX: 1 }}
        animate={{ scaleX: 0, transition: { duration: 1, ease: "circOut" } }}
        exit={{ scaleX: 1, transition: { duration: 0.4, ease: "circIn" } }}
        style={{ originX: isPresent ? 0 : 1 }}
        className="privacy-screen"
      />
    </>
  );
}

export default Projects;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM