[英]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 always
將0
作為所有 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.