programing

리액트 라우터를 사용한 루트 변경 검출

closeapi 2023. 3. 22. 21:13
반응형

리액트 라우터를 사용한 루트 변경 검출

열람 이력에 따라 몇 가지 비즈니스 로직을 구현해야 합니다.

제가 하고 싶은 일은 다음과 같습니다.

reactRouter.onUrlChange(url => {
   this.history.push(url);
});

URL이 갱신되었을 때 리액트라우터로부터 콜백을 수신하는 방법이 있습니까?

루트 변경을 검출할 때 기능을 사용할 수 있습니다.사용하고 있는 것을 생각하면react-router v4컴포넌트를 랩으로 감습니다.withRouter에 액세스하기 HOChistory

history.listen()unlisten기능.이걸 이용해서unregister고고있있있있다다

루트를 다음과 같이 설정할 수 있습니다.

index.displaces를 표시합니다.

ReactDOM.render(
      <BrowserRouter>
            <AppContainer>
                   <Route exact path="/" Component={...} />
                   <Route exact path="/Home" Component={...} />
           </AppContainer>
        </BrowserRouter>,
  document.getElementById('root')
);

다음으로 AppContainer.js로 이동합니다.

class App extends Component {
  
  componentWillMount() {
    this.unlisten = this.props.history.listen((location, action) => {
      console.log("on route change");
    });
  }
  componentWillUnmount() {
      this.unlisten();
  }
  render() {
     return (
         <div>{this.props.children}</div>
      );
  }
}
export default withRouter(App);

이력 문서:

하다 의 변화를 수 .history.listen:

history.listen((location, action) => {
      console.log(`The current URL is ${location.pathname}${location.search}${location.hash}`)
  console.log(`The last navigation action was ${action}`)
})

location 객체는 다음과 같은 window.location 인터페이스의 서브셋을 구현합니다.

**location.pathname** - The path of the URL
**location.search** - The URL query string
**location.hash** - The URL hash fragment

위치에는 다음 속성도 있을 수 있습니다.

location.state - URL에 존재하지 않는 이 로케이션의 일부 추가 상태(에서 지원됨)createBrowserHistory ★★★★★★★★★★★★★★★★★」createMemoryHistory)

location.key이됨)createBrowserHistory ★★★★★★★★★★★★★★★★★」createMemoryHistory)

은 하다, 음, , is, is, is, is 중 입니다.PUSH, REPLACE, or POP사용자가 현재 URL에 어떻게 접속했느냐에 따라 달라집니다.

반응-ru v3 액 우 트 터 우 용 하 는 경 사 when of you3-3 can react are v use youter makeou리라 usingr v를-history.listen()부에서history위에 언급된 패키지는 에 서 명 설 와 이 용 도 습 있 수 package or make다 above you can니사 also as mentioned use패할같거나하화지바browserHistory.listen()

루트를 다음과 같이 설정하고 사용할 수 있습니다.

import {browserHistory} from 'react-router';

class App extends React.Component {

    componentDidMount() {
          this.unlisten = browserHistory.listen( location =>  {
                console.log('route changes');
                
           });
      
    }
    componentWillUnmount() {
        this.unlisten();
     
    }
    render() {
        return (
               <Route path="/" onChange={yourHandler} component={AppContainer}>
                   <IndexRoute component={StaticContainer}  />
                   <Route path="/a" component={ContainerA}  />
                   <Route path="/b" component={ContainerB}  />
            </Route>
        )
    }
} 

리액트 라우터 5.1+ 업데이트

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function SomeComponent() {
  const location = useLocation();

  useEffect(() => {
    console.log('Location changed');
  }, [location]);

  ...
}

react-router v6

반응-rui v6 것, 음, 령 은 합 있 수 실-할 in react6행 v,ter-ou canr조 by다니여습하명 be6useLocation ★★★★★★★★★★★★★★★★★」useEffect훅.

import { useLocation } from 'react-router-dom';

const MyComponent = () => {
  const location = useLocation()

  React.useEffect(() => {
    // runs on location, i.e. route, change
    console.log('handle route change here', location)
  }, [location])
  ...
}

편리한 재사용용 편 한 사 재 업 스 행 있 습 니ient conven reuse for,다수수 a in do can this커작 custom you이할로으텀을위해useLocationChange hook후크

// runs action(location) on location, i.e. route, change
const useLocationChange = (action) => {
  const location = useLocation()
  React.useEffect(() => { action(location) }, [location])
}

const MyComponent1 = () => {
  useLocationChange((location) => { 
    console.log('handle route change here', location) 
  })
  ...
}

const MyComponent2 = () => {
  useLocationChange((location) => { 
    console.log('and also here', location) 
  })
  ...
}

시 해야 할 를 할 수 있습니다.usePrevious을 끼우다

const usePrevious = (value) => {
  const ref = React.useRef()
  React.useEffect(() => { ref.current = value })

  return ref.current
}

const useLocationChange = (action) => {
  const location = useLocation()
  const prevLocation = usePrevious(location)
  React.useEffect(() => { 
    action(location, prevLocation) 
  }, [location])
}

const MyComponent1 = () => {
  useLocationChange((location, prevLocation) => { 
    console.log('changed from', prevLocation, 'to', location) 
  })
  ...
}

위의 모든 것은 마운트되는 첫 번째 클라이언트루트와 그 후의 변경에 관한 것입니다.이것이 문제가 되는 경우는, 후자의 예를 사용하고, 다음의 예에 근거해,prevLocation을 사용법을 사용하다

노래를 historyglobal을 직접 를 object에 .Router 이 를 그 노래와 수 있어요.listen()★★★★

// Use Router from react-router, not BrowserRouter.
import { Router } from 'react-router';

// Create history object.
import createHistory from 'history/createBrowserHistory';
const history = createHistory();

// Listen to history changes.
// You can unlisten by calling the constant (`unlisten()`).
const unlisten = history.listen((location, action) => {
  console.log(action, location.pathname, location.state);
});

// Pass history to Router.
<Router history={history}>
   ...
</Router>

수 Import, Import 등).import history from './history';

이것은 오래된 질문이며, 저는 경로 변경을 추진하기 위해 경로 변경을 경청해야 하는 비즈니스 요구를 잘 이해할 수 없습니다. 우회적으로 보입니다.

된 , 당신이 입니다.'page_path'구글 분석/글로벌 사이트 태그/유사하게 리액트 리액트 리액트 리액트 리액트 리액트 리액트 리액트 리액트 리액트 리액트 리액트 리액트 리액트 루트나는 인정된 답변을 바탕으로 그것을 썼다.

useTracking.js

import { useEffect } from 'react'
import { useHistory } from 'react-router-dom'

export const useTracking = (trackingId) => {
  const { listen } = useHistory()

  useEffect(() => {
    const unlisten = listen((location) => {
      // if you pasted the google snippet on your index.html
      // you've declared this function in the global
      if (!window.gtag) return

      window.gtag('config', trackingId, { page_path: location.pathname })
    })

    // remember, hooks that add listeners
    // should have cleanup to remove them
    return unlisten
  }, [trackingId, listen])
}

은 앱에서 한 번 사용해야 합니다. 위쪽에 있지만 라우터 안쪽에 있어야 합니다.나는 그것을 가지고 있다App.js다음과 같이 표시됩니다.

App.js

import * as React from 'react'
import { BrowserRouter, Route, Switch } from 'react-router-dom'

import Home from './Home/Home'
import About from './About/About'
// this is the file above
import { useTracking } from './useTracking'

export const App = () => {
  useTracking('UA-USE-YOURS-HERE')

  return (
    <Switch>
      <Route path="/about">
        <About />
      </Route>
      <Route path="/">
        <Home />
      </Route>
    </Switch>
  )
}

// I find it handy to have a named export of the App
// and then the default export which wraps it with
// all the providers I need.
// Mostly for testing purposes, but in this case,
// it allows us to use the hook above,
// since you may only use it when inside a Router
export default () => (
  <BrowserRouter>
    <App />
  </BrowserRouter>
)

리액트 싱글 페이지 앱에서 새로운 화면으로 이동한 후 ChromeVox 화면 리더를 "화면" 상단에 맞추려고 하다가 이 질문을 하게 되었습니다.기본적으로 이 페이지가 로딩된 경우 서버에서 렌더링된 새로운 웹 페이지에 대한 링크를 참조하여 어떤 일이 발생할지 에뮬레이트하려고 합니다.

이 솔루션에는 청취자가 필요 없습니다.withRouter()및 그componentDidUpdate()새로운 URL 경로로 이동할 때 클릭 한 번으로 ChromeVox를 원하는 요소에 초점을 맞추는 라이프 사이클 메서드.


실행

모든 앱 화면을 포함하는 리액트 라우터 스위치 태그에 둘러싸인 "스크린" 컴포넌트를 만들었습니다.

<Screen>
  <Switch>
    ... add <Route> for each screen here...
  </Switch>
</Screen>

Screen.tsx요소

주의: 이 컴포넌트는 React + TypeScript 를 사용합니다.

import React from 'react'
import { RouteComponentProps, withRouter } from 'react-router'

class Screen extends React.Component<RouteComponentProps> {
  public screen = React.createRef<HTMLDivElement>()
  public componentDidUpdate = (prevProps: RouteComponentProps) => {
    if (this.props.location.pathname !== prevProps.location.pathname) {
      // Hack: setTimeout delays click until end of current
      // event loop to ensure new screen has mounted.
      window.setTimeout(() => {
        this.screen.current!.click()
      }, 0)
    }
  }
  public render() {
    return <div ref={this.screen}>{this.props.children}</div>
  }
}

export default withRouter(Screen)

나는 그것을 사용해 본 적이 있다.focus()대신click()를 클릭하면 ChromeVox가 현재 읽고 있는 내용을 읽지 않고 다시 시작하도록 지시하는 곳에서 시작합니다.

상세 노트:이 솔루션에서 네비게이션은<nav> 안에 , 이 컴포넌트 뒤에 됩니다.<main>에 배치되어 있습니다.main css 사용방법order: -1;다음 중 하나:

<Screen style={{ display: 'flex' }}>
  <main>
  <nav style={{ order: -1 }}>
<Screen>

이 솔루션에 대한 의견, 의견 또는 팁이 있으면 의견을 추가해 주십시오.

import React from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import Sidebar from './Sidebar';
import Chat from './Chat';

<Router>
    <Sidebar />
        <Switch>
            <Route path="/rooms/:roomId" component={Chat}>
            </Route>
        </Switch>
</Router>

import { useHistory } from 'react-router-dom';
function SidebarChat(props) {
    **const history = useHistory();**
    var openChat = function (id) {
        **//To navigate**
        history.push("/rooms/" + id);
    }
}

**//To Detect the navigation change or param change**
import { useParams } from 'react-router-dom';
function Chat(props) {
    var { roomId } = useParams();
    var roomId = props.match.params.roomId;

    useEffect(() => {
       //Detect the paramter change
    }, [roomId])

    useEffect(() => {
       //Detect the location/url change
    }, [location])
}

하다를 사용하세요.useLocation() 내의 useEffect() 에게 통했다

const App = () => {

  const location = useLocation();

  useEffect(() => {
    window.scroll(0,0);
  }, [location]);

  return (
    <React.Fragment>
      <Routes>
        <Route path={"/"} element={<Template/>} >
          <Route index={true} element={<Home/>} />
          <Route path={"cart"} element={<Cart/>} />
          <Route path={"signin"} element={<Signin/>} />
          <Route path={"signup"} element={<Signup/>} />
          <Route path={"product/:slug"} element={<Product/>} />
          <Route path={"category/:category"} element={<ProductList/>} />
        </Route>
      </Routes>
    </React.Fragment>
  );
}

export default App;

과 함께 useLocation을 할 수 .componentDidUpdate의 루트 및 「」를 해 주세요.useEffect의 경우

In Class 컴포넌트

import { useLocation } from "react-router";

class MainApp extends React.Component {
    constructor(props) {
       super(props);
    }
    async componentDidUpdate(prevProps) {
       if(this.props.location.pathname !== prevProps.location.pathname)
       {
         //route has been changed. do something here
       } 
    }
}


function App() {
 const location = useLocation()
 return <MainApp location={location} />
}

기능하고 있는 컴포넌트

function App() {
     const location = useLocation()
     useEffect(() => {
        //route change detected. do something here
     }, [location]) //add location in dependency. It detects the location change
     return <Routes> 
              <Route path={"/"} element={<Home/>} >
              <Route path={"login"} element={<Login/>} />
            </Routes>
}

리액트 라우터 V5

pathName을 문자열('/' 또는 'users')로 사용하는 경우 다음을 사용할 수 있습니다.

  // React Hooks: React Router DOM
  let history = useHistory();
  const location = useLocation();
  const pathName = location.pathname;

언급URL : https://stackoverflow.com/questions/45373742/detect-route-change-with-react-router

반응형