Nuestro equipo especializado luego de ciertos días de investigación y de recopilar de datos, dimos con los datos necesarios, nuestro deseo es que resulte útil para ti en tu plan.
Solución:
No puedo responder a la parte del “deberías” de si usar referencias para esto en lugar de si lo haces, no las necesitas. id
valores a menos que los use para otra cosa.
Pero así es como lo harías:
-
Usar
useRef(null)
para crear la ref.const activeSlideRef = useRef(null);
-
Ponlo en el
Slide
que está actualmente activo -
En tus
useEffect
, usa las referenciascurrent
propiedaduseEffect(() => if (activeSlideRef.current) activeSlideRef.current.scrollIntoView( behavior: 'smooth', block: 'nearest', inline: 'nearest' ); , [activeSlide]);
(Creo
activeSlide
es una dependencia razonable para ese efecto. No puede usar la referencia, la referencia en sí no varía …)
Ejemplo en vivo, he convertido algunos de sus componentes en div
s por conveniencia:
const useEffect, useRef, useState = React;
function Deck(children)
const [activeSlide, setActiveSlide] = useState(0);
const activeSlideRef = useRef(null);
useEffect(() =>
if (activeSlideRef.current)
activeSlideRef.current.scrollIntoView(
behavior: 'smooth',
block: 'nearest',
inline: 'nearest'
);
, [activeSlide]);
const moveLeft = Math.max(0, activeSlide - 1);
const moveRight = Math.min(children.length - 1, activeSlide + 1);
return (
children.map((child, i) =>
const active = i === activeSlide;
return (
child
);
)
);
ReactDOM.render(
slide 0
slide 1
slide 2
slide 3
slide 4
slide 5
slide 6
slide 7
slide 8
slide 9
,
document.getElementById("root")
);
.slide
height: 4em;
vertical-align: middle;
text-align: center;
#test
overflow: scroll;
max-height: 20em;
.active
font-weight: bold;
color: blue;
En un comentario has preguntado:
¿Sabe si es posible deshabilitar
useEffect
aquí para el primer render?
Para mantener información no estatal por componente, es interesante que utilice useRef
. Los documentos para useRef
señale que no es solo para referencias de elementos DOM, también es para datos no estatales por componente. Para que pudieras tener
const firstRenderRef = useRef(true);
entonces en tu useEffect
devolución de llamada, comprobar firstRenderRef.current
& mndash; si es true
, configurarlo false
, de lo contrario, haz el desplazamiento:
const useEffect, useRef, useState = React;
function Deck(children)
const [activeSlide, setActiveSlide] = useState(0);
const activeSlideRef = useRef(null);
// *** Use a ref with the initial value `true`
const firstRenderRef = useRef(true);
console.log("render");
useEffect(() =>
// *** After render, don't do anything, just remember we've seen the render
if (firstRenderRef.current)
console.log("set false");
firstRenderRef.current = false;
else if (activeSlideRef.current)
console.log("scroll");
activeSlideRef.current.scrollIntoView(
behavior: 'smooth',
block: 'nearest',
inline: 'nearest'
);
, [activeSlide]);
const moveLeft = Math.max(0, activeSlide - 1);
const moveRight = Math.min(children.length - 1, activeSlide + 1);
return (
children.map((child, i) =>
const active = i === activeSlide;
return (
child
);
)
);
ReactDOM.render(
slide 0
slide 1
slide 2
slide 3
slide 4
slide 5
slide 6
slide 7
slide 8
slide 9
,
document.getElementById("root")
);
.slide
height: 4em;
vertical-align: middle;
text-align: center;
#test
overflow: scroll;
max-height: 10em;
.active
font-weight: bold;
color: blue;
Como experimento mental, escribí un gancho para facilitar un poco la ergonomía:
function useInstance(instance = )
// assertion: instance && typeof instance === "object"
const ref = useRef(instance);
return ref.current;
Uso:
const inst = useInstance(first: true);
En useEffect
, si inst.first
es true, hacer inst.first = false;
; de lo contrario, realice el desplazamiento.
Vivir:
const useEffect, useRef, useState = React;
function useInstance(instance = )
// assertion: instance && typeof instance === "object"
const ref = useRef(instance);
return ref.current;
function Deck(children)
const [activeSlide, setActiveSlide] = useState(0);
const activeSlideRef = useRef(null);
const inst = useInstance(first: true);
console.log("render");
useEffect(() =>
// *** After render, don't do anything, just remember we've seen the render
if (inst.first)
console.log("set false");
inst.first = false;
else if (activeSlideRef.current)
console.log("scroll");
activeSlideRef.current.scrollIntoView(
behavior: 'smooth',
block: 'nearest',
inline: 'nearest'
);
, [activeSlide]);
const moveLeft = Math.max(0, activeSlide - 1);
const moveRight = Math.min(children.length - 1, activeSlide + 1);
return (
children.map((child, i) =>
const active = i === activeSlide;
return (
child
);
)
);
ReactDOM.render(
slide 0
slide 1
slide 2
slide 3
slide 4
slide 5
slide 6
slide 7
slide 8
slide 9
,
document.getElementById("root")
);
.slide
height: 4em;
vertical-align: middle;
text-align: center;
#test
overflow: scroll;
max-height: 10em;
.active
font-weight: bold;
color: blue;
Sección de Reseñas y Valoraciones
Tienes la opción de respaldar nuestra función fijando un comentario o dejando una puntuación te lo agradecemos.