리액터-루터와 함께 앵커 사용
리액션 라우터를 사용하고 특정 페이지의 특정 위치로 링크를 이동시키는 방법(예:/home-page#section-three
)
세부 정보:
나는 사용하고 있다react-router
내 리액트 앱에서.
페이지 특정 부분에 연결해야 하는 사이트 전체 탐색 모음을 가지고 있다./home-page#section-three
.
그러니 설사 당신이 명령한다 해도/blog
이 링크를 클릭하면 홈 페이지가 로드되고 섹션 3이 보기로 스크롤된다.이것이 바로 표준이다.<a href="/home-page#section-three>
효과가 있을 거야
참고: 리액션 라우터의 작성자는 명시적인 답변을 하지 않았다.그들은 그것이 진행 중이고, 그 동안 다른 사람들의 대답을 사용한다.나는 지배적인 질문이 나올 때까지 이 문제를 계속 진행과 가능한 해결책으로 업데이트 할 수 있도록 최선을 다할 것이다.
연구:
이 질문은 2015년부터입니다 (그래서 10년 전 반응 시간).가장 많이 인용된 대답은HistoryLocation
대신에HashLocation
. 기본적으로 해시 조각이 아닌 창 내역에 위치를 저장하는 것을 의미한다.
나쁜 소식은...HistoryLocation(2016년에 대부분의 튜토리얼과 문서들이 말하는 것)을 사용해도 앵커 태그는 여전히 작동하지 않는다.
https://github.com/ReactTraining/react-router/issues/394
앵커와 리액트라우터를 연결하는 방법에 대한 리액트 트레이닝의 스레드.이것은 확답이 아니다.제안된 대부분의 답변이 최신 버전이 아니므로 주의하십시오(예: "해시" 프로펠러 사용).<Link>
)
React Router Hash Link는 나에게 효과가 있으며 설치 및 구현이 쉽다.
$ npm install --save react-router-hash-link
구성 요소.js에서 연결로 가져오기:
import { HashLink as Link } from 'react-router-hash-link';
그리고 닻을 사용하는 대신에<a>
사용하다<Link>
:
<Link to="home-page#section-three">Section three</Link>
참고: 사용하였다HashRouter
대신에Router
:
여기 내가 찾은 한 가지 해결책(2016년 10월)이 있다.크로스 브라우저 호환(Internet Explorer, Firefox, Chrome, 모바일 Safari 및 Safari에서 테스트됨)
다음을 제공할 수 있다.onUpdate
라우터에 대한 속성.이것은 경로가 업데이트될 때마다 불린다.이 솔루션은 onUpdate 속성을 사용하여 해시와 일치하는 DOM 요소가 있는지 확인한 후 경로 전환이 완료된 후 해당 요소로 스크롤한다.
hashHistory가 아닌 브라우저History를 사용해야 한다.
해시 링크 #394의 "Rrafracs"에 의한 답이다.
정의한 위치에 이 코드 추가<Router>
:
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';
const routes = (
// your routes
);
function hashLinkScroll() {
const { hash } = window.location;
if (hash !== '') {
// Push onto callback queue so it runs after the DOM is updated,
// this is required when navigating from a different page so that
// the element is rendered on the page before trying to getElementById.
setTimeout(() => {
const id = hash.replace('#', '');
const element = document.getElementById(id);
if (element) element.scrollIntoView();
}, 0);
}
}
render(
<Router
history={browserHistory}
routes={routes}
onUpdate={hashLinkScroll}
/>,
document.getElementById('root')
)
만약 당신이 게을러지고 있고 그 코드를 복사하고 싶지 않다면, 당신은 단지 당신을 위해 그 기능을 정의하는 Anchoch를 사용할 수 있다.https://github.com/adjohnson916/anchorate
이 솔루션은 리액터 v5와 함께 작동함
import React, { useEffect } from 'react'
import { Route, Switch, useLocation } from 'react-router-dom'
export default function App() {
const { pathname, hash, key } = useLocation();
useEffect(() => {
// if not a hash link, scroll to top
if (hash === '') {
window.scrollTo(0, 0);
}
// else scroll to id
else {
setTimeout(() => {
const id = hash.replace('#', '');
const element = document.getElementById(id);
if (element) {
element.scrollIntoView();
}
}, 0);
}
}, [pathname, hash, key]); // do this on route change
return (
<Switch>
<Route exact path="/" component={Home} />
.
.
</Switch>
)
}
구성 요소에서
<Link to="/#home"> Home </Link>
여기에 구독이나 타사 패키지가 필요하지 않은 간단한 솔루션이 있다.와 잘 어울려야 한다.react-router@3
그 이상 그 이상.react-router-dom
.
작업 예: https://fglet.codesandbox.io/
소스(불행히도 현재 편집기 내에서 작동하지 않음):
#스크롤핸들러 후크 예
import { useEffect } from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router-dom";
const ScrollHandler = ({ location, children }) => {
useEffect(
() => {
const element = document.getElementById(location.hash.replace("#", ""));
setTimeout(() => {
window.scrollTo({
behavior: element ? "smooth" : "auto",
top: element ? element.offsetTop : 0
});
}, 100);
}, [location]);
);
return children;
};
ScrollHandler.propTypes = {
children: PropTypes.node.isRequired,
location: PropTypes.shape({
hash: PropTypes.string,
}).isRequired
};
export default withRouter(ScrollHandler);
#스크롤핸들러 클래스 예
import { PureComponent } from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router-dom";
class ScrollHandler extends PureComponent {
componentDidMount = () => this.handleScroll();
componentDidUpdate = prevProps => {
const { location: { pathname, hash } } = this.props;
if (
pathname !== prevProps.location.pathname ||
hash !== prevProps.location.hash
) {
this.handleScroll();
}
};
handleScroll = () => {
const { location: { hash } } = this.props;
const element = document.getElementById(hash.replace("#", ""));
setTimeout(() => {
window.scrollTo({
behavior: element ? "smooth" : "auto",
top: element ? element.offsetTop : 0
});
}, 100);
};
render = () => this.props.children;
};
ScrollHandler.propTypes = {
children: PropTypes.node.isRequired,
location: PropTypes.shape({
hash: PropTypes.string,
pathname: PropTypes.string,
})
};
export default withRouter(ScrollHandler);
로컬 스크롤에 반응 라우터를 사용하지 마십시오.
document.getElementById('myElementSomewhere').scrollIntoView()
Don P의 답변에 대한 문제는 때때로 해당 섹션이 비동기 동작에 의존하는 경우 ID가 있는 요소가 여전히 렌더링되거나 로드된다는 것이다.다음 기능은 id로 요소를 찾아 탐색한 후 최대 50번의 재시도에 도달할 때까지 100ms마다 재시도한다.
scrollToLocation = () => {
const { hash } = window.location;
if (hash !== '') {
let retries = 0;
const id = hash.replace('#', '');
const scroll = () => {
retries += 0;
if (retries > 50) return;
const element = document.getElementById(id);
if (element) {
setTimeout(() => element.scrollIntoView(), 0);
} else {
setTimeout(scroll, 100);
}
};
scroll();
}
}
Don P의 솔루션(위 참조)을 에 적응시켰다.react-router
4 (2019년 1월)이 없기 때문에onUpdate
을 떠받치다.<Router>
더 이상
import React from 'react';
import * as ReactDOM from 'react-dom';
import { Router, Route } from 'react-router';
import { createBrowserHistory } from 'history';
const browserHistory = createBrowserHistory();
browserHistory.listen(location => {
const { hash } = location;
if (hash !== '') {
// Push onto callback queue so it runs after the DOM is updated,
// this is required when navigating from a different page so that
// the element is rendered on the page before trying to getElementById.
setTimeout(
() => {
const id = hash.replace('#', '');
const element = document.getElementById(id);
if (element) {
element.scrollIntoView();
}
},
0
);
}
});
ReactDOM.render(
<Router history={browserHistory}>
// insert your routes here...
/>,
document.getElementById('root')
)
<Link to='/homepage#faq-1'>Question 1</Link>
useEffect(() => {
const hash = props.history.location.hash
if (hash && document.getElementById(hash.substr(1))) {
// Check if there is a hash and if an element with that id exists
document.getElementById(hash.substr(1)).scrollIntoView({behavior: "smooth"})
}
}, [props.history.location.hash]) // Fires when component mounts and every time hash changes
간단한 페이지 내 네비게이션의 경우 페이지 초기화를 처리하지는 않지만 이와 같은 내용을 추가할 수 있다.
// handle back/fwd buttons
function hashHandler() {
const id = window.location.hash.slice(1) // remove leading '#'
const el = document.getElementById(id)
if (el) {
el.scrollIntoView()
}
}
window.addEventListener('hashchange', hashHandler, false)
대안: react-resignchor https://www.npmjs.com/package/react-scrollchor
react-scrollchor: 부드러운 애니메이션으로 #hash 링크로 스크롤할 수 있는 React 구성 요소.Scrollchor는 Scroll과 Anchor를 혼합한 것이다.
참고: 리액트라우터를 사용하지 않음
참조URL: https://stackoverflow.com/questions/40280369/use-anchors-with-react-router
'Programing' 카테고리의 다른 글
ReactCSSTranscriptionGroup 및 React Router를 통해 복잡한 애니메이션이 가능하십니까? (0) | 2022.03.13 |
---|---|
Vuetify 버튼의 텍스트 색상을 변경하는 방법 (0) | 2022.03.13 |
vue-roouter에서 각 처리기를 설정하는 방법 (0) | 2022.03.13 |
클릭 시 중첩된 JSON-Data 탐색 (0) | 2022.03.13 |
파이톤 3의 로_input()과 인풋()의 차이점은 무엇일까. (0) | 2022.03.13 |