programing

react-router-dom useParams() inside 클래스 컴포넌트

skycolor 2023. 3. 8. 20:59
반응형

react-router-dom useParams() inside 클래스 컴포넌트

URL 파라미터(id)를 취득하여 컴포넌트를 추가 입력하기 위해 사용해야 하는 react-router-dom 루트를 기반으로 상세 뷰를 로드하려고 합니다.

.../task/:id이치노URL : id 를를를 。

import React from "react";
import { useParams } from "react-router-dom";

class TaskDetail extends React.Component {
    componentDidMount() {
        let { id } = useParams();
        this.fetchData(id);
    }

    fetchData = id => {
        // ...
    };

    render() {
        return <div>Yo</div>;
    }
}

export default TaskDetail;

이로 인해 다음 오류가 발생하며 useParams()를 어디에 올바르게 구현해야 할지 잘 모르겠습니다.

Error: Invalid hook call. Hooks can only be called inside of the body of a function component.

이 문서에서는 클래스 베이스가 아닌 기능 컴포넌트에 근거한 예만 보여 줍니다.

버전 <= 5:

하시면 됩니다.withRouter네, 네, 네. 를 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★withRouter ""를 사용할 수 .this.props.match.params.iduseParams() 도 받을 수 요.location,match , 「」history, 「」를 withRouter모두 아래쪽으로 넘어갑니다.this.props

예를 들면 다음과 같습니다.

import React from "react";
import { withRouter } from "react-router";

class TaskDetail extends React.Component {
    componentDidMount() {
        const id = this.props.match.params.id;
        this.fetchData(id);
    }

    fetchData = id => {
        // ...
    };

    render() {
        return <div>Yo</div>;
    }
}

export default withRouter(TaskDetail);

그렇게 간단해!

import React, { Component } from "react";
import { useParams } from "react-router-dom";

function withParams(Component) {
  return props => <Component {...props} params={useParams()} />;
}


class TaskDetail extends React.Component {
    componentDidMount() {
        let { id } = this.props.params;
        this.fetchData(id);
    }

    fetchData = id => {
        // ...
    };

    render() {
        return <div>Yo</div>;
    }
}

export default withParams(TaskDetail);

후크는 클래스 기반 컴포넌트에서는 동작하지 않기 때문에 함수로 랩하여 속성을 전달할 수 있습니다.

class TaskDetail extends React.Component {
    componentDidMount() {
        const { id } = this.props.params;
        // ...
    }
}

export default (props) => (
    <TaskDetail
        {...props}
        params={useParams()}
    />
);

말한 @michael-mayo는 이렇게 될 합니다.withRouter이미 수행 중입니다.

패럴럼은 성냥 물체의 소품을 통해 전해집니다.

props.match.params.yourParams

출처 : https://redux.js.org/advanced/usage-with-react-router

다음은 논쟁의 소품을 파괴하는 문서들의 예입니다.

const App = ({ match: { params } }) => {
  return (
    <div>
      <AddTodo />
      <VisibleTodoList filter={params.filter || 'SHOW_ALL'} />
      <Footer />
    </div>
  )
}

React에서 "useParams()"와 같은 후크를 호출할 수 없습니다.요소.

후크를 사용하여 기존 react.component를 사용하는 가장 쉬운 방법은 함수를 만들고 React를 호출하는 것입니다.해당 함수의 구성 요소를 전달하고 매개 변수를 전달합니다.

import React from 'react';
import useParams from "react-router-dom";

import TaskDetail from './TaskDetail';

function GetId() {

    const { id } = useParams();
    console.log(id);

    return (
        <div>
            <TaskDetail taskId={id} />
        </div>
    );
}

export default GetId;

스위치 루트는 다음과 같습니다.

<Switch>
  <Route path="/task/:id" component={GetId} />
</Switch>

그러면 반응 컴포넌트의 소품에서 ID를 얻을 수 있습니다.

this.props.taskId

react-router-dom-v6에서는 기능 컴포넌트에서 Params()를 쉽게 사용할 수 있지만 클래스 컴포넌트에 대해서는 후크가 클래스 컴포넌트를 지원하지 않기 때문에 HOC(고차 컴포넌트)를 작성해야 합니다.

import { useNavigate, useParams } from "react-router-dom";

export const withRouter = (WrappedComponent) => (props) => {
  const params = useParams();
  const navigate = useNavigate();

  return <WrappedComponent {...props} params={params} navigate={navigate} />;
};

그런 다음 HOC에서 컴포넌트를 내보내고 컴포넌트를 파라미터로 지정합니다.다음과 같습니다.

export default withRouter(YourComponentName);

후 ID, url ID 에 、 id 、 id 、 id 、 id after after after after after the the the the the the the the the the the the the the the the the the the 에 쉽게 접근할 수 .this.props.params.id 보면 할 수 요.this.props.navigate("/YourPath")

리액트 루트 v5

는 JSON으로 처리할 수 있습니다.JSON으로 할 수 .withRouter ★★★★★★★★★★★★★★★★★」queryString음음음같 뭇매하다

import React from "react";
import { withRouter } from "react-router";
import queryString from 'query-string';
    
class MyComponent extends React.Component {
    componentDidMount() {
        const params = queryString.parse(this.props.location.search);
        console.log('Do something with it', params);
    }

    render() {
        return <div>Hi!</div>;
    }
}

export default withRouter(MyComponent);

SmujMaiku는 리그!!그의 대답은 완벽하게 들어맞는다.이것이 현재 리액트 라우터 v6의 동작 방식입니다.

enter code here
   
   import React ,{Component} from 'react'
   import {  useParams } from "react-router-dom";
  import PokeDescription from '../components/PokeDescription'

 class PokeInfoConteiner extends Component{

 render(){
    
    let urlPokemon= "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/"
    
    
    const {idPokemon} = this.props.params 
    console.log(idPokemon)

    return(
        
        <div>
            <PokeDescription pokeImage={`${urlPokemon}${idPokemon}.png?raw=true`}/>
            <p>{}</p>
            
        </div>

    )

}

}

   export default (props) => (
        <PokeInfoConteiner
            {...props}
            params={useParams()}
   />)

리액트 라우터 V6:

import React, {Component} from 'react';
import {useParams} from 'react-router-dom';

/* This is a higher order component that 
*  inject a special prop   to our component.
*/ 
function withRouter(Component) {
  function ComponentWithRouter(props) {
    let params = useParams()
    return <Component {...props} params={params} />
  }
  return ComponentWithRouter
}
class TaskDetail extends React.Component {
    state={
      id : ""
    }
    componentDidMount() {
      this.setState({
        id : this.props.params.id
      })
    }
    static getDerivedStateFromProps(nextProps) {
      return {
        id : nextProps.params.id
      }
    }
    fetchData = id => {
        // ...
    };

    render() {
        return <div>Yo</div>;
    }
}


const HOCTaskDetail = withRouter(TaskDetail);

export default HOCTaskDetail;

리액트 루트 v6

친구들, 수업시간에 사용하려고 했는데 어떤 문서도 찾지 못했어요.그래서 여러 시간 동안 찾고 노력한 결과 이것이 작동하게 되었다.v6에 대한 리소스는 한정되어 있습니다.그러나 <v6>에는 많은 것이 있습니다.

useState, useEffect, useParams, axios를 사용하고 있습니다.

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import axios from 'axios';

const Post = () => {
    let { post_id } = useParams();
    const [posts, setPosts] = useState({ post: null, countSecrets: 0, ui: '' });

    useEffect(() => {
        if (posts.countSecrets === 0) {
            const doAxe = (a) => {
                axios.get('https://jsonplaceholder.typicode.com/posts/' + post_id)
                    .then((res) => {
                        setPosts(s => ({ ...s, value: res.data }));
                        doUI(res.data)
                        // console.log(res.data)
                    });
            }
            setPosts(s => ({ ...s, countSecrets: s.countSecrets + 1 }));
            doAxe()
        }
    }, [posts, post_id]);
    let doUI = (x) => {
        // console.log('x' + x.title)
        const finalPost = (x !== null) ? (
            <div className="post">
                <h4 className="center">{x.title}</h4>
                <p>{x.body}</p>
            </div>
        ) : (
            <div className="center">Loading posts...</div>
        );
        setPosts(s => ({ ...s, ui: finalPost }));
    }
    return (
        <div className="container">
            {posts.ui}
        </div>
    );
}

export default Post;

메모: useEffect 루프에 직면했습니다.열쇠로 막았어요.

호프: 이게 도움이 될 수도 있어!

레퍼런스:

react-router-dom v6에서는 withRouter와 같은 후크는 없으므로 클래스 기반 컴포넌트를 기능 컴포넌트로 변환하여 컴포넌트에서 useParams 훅을 사용하는 것이 좋습니다.그렇지 않으면 클래스 기반 컴포넌트를 전달하기 위한 상위 컴포넌트를 작성할 수 있습니다.

아시다시피 useParams()는 react-router-dom의 후크입니다.componentDidMount() 또는 useEffect()에서는 사용할 수 없습니다.이것은 둘 다 React Life-Cycle의 마운트 단계(컴포넌트가 렌더링된 후) 중에 호출된 메서드이기 때문입니다.솔루션이 있습니다. componentDidMount() 외부에서 다른 함수를 만들거나 정의하여 useParams를 정의하고 componentDidMount 내에서 호출합니다.모든 게 잘 될 거라는 걸 알아

이것이 저의 작업 예시입니다.:)

import React, { Component } from "react";
import { useParams } from "react-router-dom";

function withParams(Component) {
  return (props) => <Component {...props} params={useParams()} />;
}

class ProductDetails extends Component {
  handleSave = () => {
    // Navigate to /products
  };

  render() {
    return (
      <div>
        <h1>Product Details - {this.props.params.id}</h1>
        <button onClick={this.handleSave}>Save</button>
      </div>
    );
  }
}

export default withParams(ProductDetails);

후크는 기능 컴포넌트에서만 동작합니다.기능 컴포넌트를 기능 컴포넌트로 만들어야 합니다.

포장 기능을 만들어 고정

react-router-dom v6를 사용하여 index.js에서 SaxjaxApp.js로 파라미터를 전달해야 했습니다.v6에서는Switch로 변경되었습니다.Routes

나는 Mohamed MAZEK의 아이디어를 포장기능으로 따라 클래스 컴포넌트로 작업하는 useParams를 얻었다.

에 액세스 할 필요가 있었습니다.sessionId사용 가능한 URL의 일부입니다.

즉,localhost:3000/shared/123XYZId나는 그 것이 필요했다.123XYZId일부.

다음 행에 주의해 주세요.<Route path="/shared/:sessionId" element={<SaxjaxAppWrapper />} />를 참조해 주세요.

:sessionId를 나타냅니다.useParams라고 하는 속성을 가지고 있다.sessionId다음 사용자가 접근할 수 있는 사용자:

const {sessionId} = useParams()기능 컴포넌트로부터 해방됩니다.

index.js 파일에서 다음과 같이 했습니다.

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter, Route, Routes } from "react-router-dom";

import "./styles/style.scss";

import SaxjaxAppWrapper from "SaxjaxAppWrapper";
import SaxjaxApp from "./SaxjaxApp";

const container = document.getElementById("root");
const root = ReactDOM.createRoot(container);
//INFO: to learn about react-roue-dom v6 https://reactrouter.com/en/v6.3.0/upgrading/v5

root.render(
  // <React.StrictMode>
  <BrowserRouter>
    <Routes>
      <Route path="/shared/:sessionId" element={<SaxjaxAppWrapper />} />
      <Route path="/" element={<SaxjaxApp />} />
    </Routes>
  </BrowserRouter>
  // </React.StrictMode>
);

이 행<Route path="/shared/:sessionId" element={<SaxjaxAppWrapper />} />기본 경로인 반면, 내 래핑 함수를 호출합니다./클래스 컴포넌트를 호출합니다.

래핑 기능을 유지하기 위해 별도의 파일을 생성해야 했습니다. 이유는 알 수 없습니다.

import React from "react";
import { useParams } from "react-router-dom";
import SaxjaxApp from "SaxjaxApp";
    
 function SaxjaxAppWrapper() {

//I use the params here and store them to pass as props 
  let { sessionId } = useParams();

  return (
//I pass the sessionId from the url params as a prop to my SaxjaxApp class component here
      <SaxjaxApp sessionId={sessionId} />
  );
}
    
export default SaxjaxAppWrapper;

내 클래스 구성 요소:

import React, { Component } from "react";
import "./styles/style.scss";

class SaxjaxApp extends Component {
 state = {
   octave: 4,
 };

 constructor(props) {
   super(props);
   //... initialise stuff
 }

//... a lot of methods

render() {
//Access the param here
   const { sessionId } = this.props;
     <>
         <div>
           keybordId={sessionId ? sessionId : "no id was passed"}
         </div>
     </>

   );
 }
}

export default SaxjaxApp;

언급URL : https://stackoverflow.com/questions/58548767/react-router-dom-useparams-inside-class-component

반응형