How to scroll to element of the list in other component?

How to scroll to element of the list in other component?



How to scroll to element of the list in other component?


class Posts extends Components
render()
<ul>
this.props.posts.map((post) =>
<li key=post.id>post.title</li>
)
</ul>


//redux


class OtherComponent extends Components
onClickHandler = (id) =>
//!!!!!!!!
//scroll page to li with key=post.id


render()
<div>
this.props.posts.map((post) =>
<div key=post.id onClick=() => this.onClickHandler(post.id)>post.title</div>
)
</div>


//redux



I found solutions here: ReactJS how to scroll to an element



but all are for single element.



If I have list, I need to create a reference to everyone? The list of posts can change, so I can not do it.






How those 2 components are connected?

– Arup Rakshit
Sep 18 '18 at 19:29






By redux, but in app both are in the same "level"

– tolu
Sep 18 '18 at 19:31




1 Answer
1



You can build an index of refs based on the key of the item when iterating over the list, then use that key to lookup the ref and invoke scrollIntoView on the element.


refs


scrollIntoView



UPDATE: Revised code example now shows how to store the list of refs in a child component and invoke a function on that child component to scroll to a particular item in the list. Using refs, you can call a function on a child component instance. This isn't ideal since it breaks out of React's declarative model, but in some situations, particularly around interacting directly with DOM elements for focus or scrolling, it is needed. If you haven't already I also suggest reading the brief React guide to Refs and the DOM, as well as Forwarding Refs and how they may be helpful.




const items = Array.from(new Array(1000).keys()).map(m => (
id: m + 1,
name: `Item $m + 1`
));

const ComponentA = ( children, onClick ) => (
<button type="button" onClick=onClick>
children
</button>
);

class ComponentB extends React.Component
constructor(props, context)
super(props, context);

this.itemRefs = ;


scrollTo(id)
this.itemRefs[id].scrollIntoView();


render()
return (
<ul>
items.map(m => (
<li key=m.id ref=el => (this.itemRefs[m.id] = el)>
m.name
</li>
))
</ul>
);



class App extends React.Component
render()
return (
<div>
<ComponentA onClick=() => this.listComponent.scrollTo(1000)>
Jump to Item 1000
</ComponentA>
<ComponentB ref=e => (this.listComponent = e) />
<ComponentA onClick=() => this.listComponent.scrollTo(1)>
Jump to Item 1
</ComponentA>
</div>
);



const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);


<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>






Thanks, but what if the buttons are in a different component than the list? Both are in the same level and are childrens of App.

– tolu
Sep 19 '18 at 16:53







Check out my updated answer that uses a child component example.

– Tyler
Sep 20 '18 at 1:54



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)