Espero que mi enfoque para esto sea correcto, pero estoy tratando de crear un componente en React donde un montón de publicaciones se representan en una vista de columna apiladas una encima de la otra, cada publicación individual se establece en 100vh.
Pseudocódigo
<container ref={postRef}> <post 1/> <post 2/> <post 3/> </container> Tengo una ref en el <container/> y de la función onClick de otro componente obtengo el índice actual de la <post/> en la que hice clic, y luego encuentro ese elemento en el dom.
useEffect(() => { if (postRef.current && indexOfClickedPost) { const refBounds = postRef.current.children[indexOfClickedPost].getBoundingClientRect() window.scrollTo({ top: // which unit goes here? }); } }) mi objetivo final es desplazar mi componente <container/> hasta la parte superior de la publicación en relación con el que se acaba de hacer clic.
Ex. si el usuario hace clic en una publicación con un índice de 2, la página se desplazará hasta donde comienza la publicación 2 div
No estoy seguro de qué unidad debo poner en mi window.scrollTo para obtener ese efecto. Poner refBounds.top no produce los resultados que quiero, parece que no hace nada en absoluto por lo que puedo ver visiblemente. Cualquier consejo sería genial. ¡Gracias!
Propongo dos enfoques diferentes, el primero sigue su prueba y utiliza getBoundingClientRect() para calcular la distancia correcta desde la parte superior y scrollTo para desplazarse a ese elemento:
function App() { const [currPostIdx, setCurrPostIdx] = useState(0); const containerRef = useRef(); const selectPost = (idx) => { setCurrPostIdx(idx); }; useEffect(() => { const el = containerRef.current.children[currPostIdx]; const top = window.pageYOffset + el.getBoundingClientRect().top; console.log(currPostIdx, top); window.scrollTo(0, top); }, [currPostIdx]); return ( <> <ul className="navbar"> {posts.map((p, i) => ( <li key={p.title} onClick={() => selectPost(i)}> {p.title} </li> ))} </ul> <div ref={containerRef}> {posts.map((p, idx) => ( <Post key={p.title} post={p} idx={idx} /> ))} </div> </> ); } const Post = ({ idx, post }) => ( <div id={post.title} className="post" style={{ backgroundColor: `#${idx + 5}${idx * 3}${idx * 4}` }} > <h4>{post.title}</h4> </div> );Demostración AQUÍ
El segundo enfoque hace uso de la navegación hash y, por lo tanto, no tiene que calcular la posición del elemento manualmente:
function App() { return ( <div> <div className="navbar"> {posts.map((p) => ( <a href={`#${p.title}`}>{p.title}</a> ))} </div> {posts.map((p, idx) => ( <Post key={p.title} post={p} idx={idx} /> ))} </div> ); } const Post = ({ idx, post }) => ( <div id={post.title} className="post" style={{ backgroundColor: `#${idx + 5}${idx * 3}${idx * 4}` }} > <h4>{post.title}</h4> </div> );Demostración AQUÍ