Manage a list of Refs using a ref callback

  • React.Ref.callbackDomRef()
@send external scrollIntoView: (Dom.element, {..}) => unit = "scrollIntoView" let getCatList = () => { let cats = [] for i in 0 to 10 { cats->Belt.Array.push({ "id": i, "url": "https://placekitten.com/250/200?image=" ++ Js.Int.toString(i), }) } cats } module CatList = { let cats = getCatList() @react.component let make = () => { let itemsRef = React.useRef(Belt.MutableMap.Int.make()) let scrollToId = id => { let m = itemsRef.current switch Belt.MutableMap.Int.get(m, id) { | Some(e) => scrollIntoView( e, { "behavior": "smooth", "block": "nearest", "inline": "center", }, ) | None => () } } <> <div className="flex flex-col p-4 items-start justify-center"> <nav className="flex gap-2 pb-2"> <button type_="button" className="p-2 bg-slate-200" onClick={_ => scrollToId(1)}> {"Tome"->React.string} </button> <button type_="button" className="p-2 bg-slate-200" onClick={_ => scrollToId(5)}> {"Remy"->React.string} </button> <button type_="button" className="p-2 bg-slate-200" onClick={_ => scrollToId(9)}> {"Jack"->React.string} </button> </nav> </div> <div className="flex p-4 overflow-x-auto"> <ul className="flex gap-2"> {cats ->Belt.Array.map(cat => { <li className="flex-none" ref={ReactDOM.Ref.callbackDomRef(element => { let m = itemsRef.current switch element->Js.Nullable.toOption { | Some(e) => Belt.MutableMap.Int.set(m, cat["id"], e) | None => Belt.MutableMap.Int.remove(m, cat["id"]) } })}> <img src={cat["url"]} className="w-[20rem] h-[16rem]" /> </li> }) ->React.array} </ul> </div> </> } } @react.component let make = () => { <CatList /> }