I'm having trouble with react. I'm trying to implement a simple scrollable div that contains a lot of child divs that can be viewed with horizontal scrolling.
Basically each child div corresponds to a day. This component loads the first time a user views information about the current day and the following days. However, if the user scrolls (left or right), I would like to be able to append more information, implementing some kind of "infinite scroll functionality".
When I try to append a new child div at the end of the parent div, I don't have any problems. However, when I try to append a new child element at the beginning of the parent div (e.g. the user wants to see content from previous days), the scroll changes after adding the new element, causing the user to be confused as to why the scroll is changing .
I created a small JS fiddle to replicate my setup. Try clicking "Add Left" and you will see the current behavior. Is there a way to add new elements without changing the entire view? https://jsfiddle.net/k75pvey3/3/
P.s. I saw a lot of answers to this question online. However, all of these I've seen assume that the new component has a specific width. In my case (as I'm trying to show in the fiddle), I can't determine the width of the newly added child div.
Here is the code for reference:
function App(props) { const [array, setArray] = React.useState(['100', '321', '32', '412', '12', '33', '54']) const addLeft = () => { setArray([Math.floor(Math.random()*300), ...array]) } const addRight = () => { setArray([...array, Math.floor(Math.random()*300)]) } return ( <div className='App'> <button onClick={addLeft}>add left</button> <button onClick={addRight}>add right</button> <div className="container"> {array.map(i => (<div className="element" style={{minWidth:i}}>{i}</div>))} </div> </div> ); } ReactDOM.render(<App />, document.querySelector("#app"))
This is the CSS:
.container { background-color: red; width: 550px; height: 120px; margin: auto; display: flex; overflow: auto; } .element { height: 100px; background-color: yellow; margin: 10px; font-size: 30px; color: black; display: flex; }
I have bad news for you, this is usually one of the complicated parts of virtual lists - adding a new element at the beginning of the scroll axis while maintaining the scroll position.
It is usually recommended that you use an existing solution such as
react-virtualized
orreact-window
.If you don't want to use an existing library, one solution is that you can listen to the
width
of the content inside thediv
(eg.Element.scrollWidth
), and then set the value of the.scrollLeft
container. However, things get complicated when you load while scrolling, as scrolling can be "with inertia", especially on touchscreen devices/touchpads on laptops.(As a rule of thumb, when I'm overconfident I can write a dummy list myself and end up using the library due to a lot of edge cases)