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.
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
How those 2 components are connected?
– Arup Rakshit
Sep 18 '18 at 19:29