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.
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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With