可以说我有组件“ Post”,其中包含多个组件“ Comment”。当我输入如下网址时,我想使该应用程序向下滚动到具有该锚点的注释:
private static void getEmployees()
{
final String uri = "http://localhost:8080/springrestexample/employees.xml";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);
System.out.println(result);
}
我已经在使用postId路由/post/:postId/#commentId
我试图用react-hash-link npm包实现它,但是它没有按预期工作。
每个注释都具有在组件上设置的自己的ID,如下所示:
/post/:postId
例如,如果我打开如下网址:
<div class="post">
<div class="post-header">
<div class="post-header-avatar">
SOME TEXT
</div>
<div class="post-header-info">
SOME TEXT
</div>
</div>
<div class="post-content">
<span>POST CONTENT</span>
</div>
<div class="post-likers-container">
<div class="post-likers-header label">People who like this post</div>
<div class="post-likers">
SOME TEXT
</div>
</div>
<div class="post-comments">
<div class="comments ">
<div class="comments-all label">Comments</div>
<div class="comments">
<div class="comment" id="5d27759edd51be1858f6b6f2">
<div class="comment-content">
COMMENT 1 TEXT
</div>
</div>
<div class="comment" id="5d2775b2dd51be1858f6b720">
<div class="comment-content">
COMMENT 2 TEXT
</div>
</div>
<div class="comment" id="5d2775ecdd51be1858f6b753">
<div class="comment-content">
COMMENT 3 TEXT
</div>
</div>
</div>
</div>
</div>
</div>
我想打开帖子页面,并使用#锚点向下滚动到评论。
有什么办法可以实现这一目标?
答案 0 :(得分:1)
我真的很喜欢您的解决方案@SaltyTeemooo。受到它的启发,我发现了没有任何回调的更简单的方法。
我的设置非常相似,所以可以说我正在处理帖子和评论。
在Post
中,我像这样创建Comment(简化)并传递anchorId:
<Comments anchorId={window.location.href.slice(window.location.href.indexOf("#") + 1)} props... />
在Comments
中,将锚点ID传递到Comment.js
<Comment anchorId={props.anchorId} props.../>
然后在Comment
中,将当前元素滚动到视图中(如果它是链接的元素)
import React, { useRef, useEffect } from 'react';
function Comment () {
const comment = useRef(null); //to be able to access the current one
useEffect(() => {
if(props.anchorId === props.commentData.id)
{
comment.current.scrollIntoView({ behavior: "smooth" });
}
}, []) //same as ComponentDidMount
return(
<div id={props.commentData.id} ref={comment}> //here is where the ref gets set
...
</div>
)
}
答案 1 :(得分:0)
保证...
import React, { useEffect } from 'react';
const MainApp = () => {
const MyRef = React.createRef();
useEffect(() => { // Same like ComponentDidMount().
scrollTo();
})
const scrollTo = () => {
window.scrollTo({
top:myRef.offsetTop,
behavior: "smooth" // smooth scroll.
});
}
return (
<div ref={MyRef}>My DIV to scroll to.</div>
)
}
答案 2 :(得分:0)
花相当多的时间,但是请尝试以下沙箱:https://codesandbox.io/s/scrollintoview-with-refs-and-redux-b881s
这将为您提供大量有关如何使用URL参数滚动到元素的见识。
import React from "react";
import { connect } from "react-redux";
import { getPost } from "./postActions";
class Post extends React.Component {
constructor(props) {
super(props);
this.state = {
activeComment: null
};
this._nodes = new Map();
}
componentDidMount() {
this.props.getPost(this.props.match.params.id);
const path = window.location.href;
const commentId = path.slice(path.indexOf("#") + 1);
if (commentId) {
this.setState({
activeComment: commentId
});
}
}
componentDidUpdate(prevProps, prevState) {
if (this.state.activeComment !== prevState.activeComment) {
this.scrollToComment();
}
}
scrollToComment = () => {
const { activeComment } = this.state;
const { comments } = this.props.posts.post;
const nodes = [];
//Array.from creates a new shallow-copy of an array from an array-like or iterable object
Array.from(this._nodes.values()) //this._nodes.values() returns an iterable-object populated with the Map object values
.filter(node => node != null)
.forEach(node => {
nodes.push(node);
});
const commentIndex = comments.findIndex(
comment => comment.id == activeComment
);
if (nodes[commentIndex]) {
window.scrollTo({
behavior: "smooth",
top: nodes[commentIndex].offsetTop
});
}
};
createCommentList = () => {
const { post } = this.props.posts;
const { activeComment } = this.state;
if (post) {
return post.comments.map((comment, index) => {
return (
<div
key={comment.id}
className={
"comment " + (activeComment == comment.id ? "activeComment" : "")
}
ref={c => this._nodes.set(comment.id, c)}
>
{comment.text}
</div>
);
});
}
};
displayPost = () => {
const { post } = this.props.posts;
if (post) {
return (
<div className="post">
<h4>{post.title}</h4>
<p>{post.text}</p>
</div>
);
}
};
render() {
return (
<div>
<div>{this.displayPost()}</div>
<div>{this.createCommentList()}</div>
</div>
);
}
}
const mapStateToProps = state => {
return {
posts: state.posts
};
};
const mapDispatchToProps = dispatch => {
return {
getPost: postId => {
dispatch(getPost(postId));
}
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(Post);
答案 3 :(得分:0)
我设法为我的用例找到了简单的解决方案,而没有为引用创建引用,也没有传递引用等。由于我的组件层次结构是这样的:
Post
->渲染组件Comments
Comments
->渲染
从Comment
传递道具数据的多个组件Post
在Post
组件中,我创建了函数:
scrollToComment= () => {
let currentLocation = window.location.href;
const hasCommentAnchor = currentLocation.includes("/#");
if (hasCommentAnchor) {
const anchorCommentId = `${currentLocation.substring(currentLocation.indexOf("#") + 1)}`;
const anchorComment = document.getElementById(anchorCommentId);
if(anchorComment){
anchorComment.scrollIntoView({ behavior: "smooth" });
}
}
}
然后我像这样渲染Comments
:
<Comments limit={limit} post={post} scrollToComment={this.scrollToComment} />
在Comments
中,我经过如下排序后生成评论:
{sortedComments.map((comment, i) => <Comment key={i} {...comment} scrollToComment={this.props.scrollToComment}/> )}
最后在Comment
组件中,我在scrollToComment
中执行ComponentDidMount()
:
if(this.props.scrollToComment)
this.props.scrollToComment(this.props._id);
之后,当我转到某个URL时,可以平滑滚动到URL哈希部分中指定的注释。
我尝试了@Christopher解决方案,但对我没有用。