【问题标题】:React Router Pass Param to ComponentReact Router 将参数传递给组件
【发布时间】:2018-02-04 12:43:52
【问题描述】:
const rootEl = document.getElementById('root');

ReactDOM.render(
    <BrowserRouter>
        <Switch>
            <Route exact path="/">
                <MasterPage />
            </Route>
            <Route exact path="/details/:id" >
                <DetailsPage />
            </Route>
        </Switch>
    </BrowserRouter>,
    rootEl
);

我正在尝试访问 DetailsPage 组件中的 id,但它无法访问。我试过了

<DetailsPage foo={this.props}/>

向DetailsPage传递参数,但徒劳无功。

export default class DetailsPage extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div className="page">
            <Header />
            <div id="mainContentContainer" >

            </div>
            </div>
    );
    }
}

那么知道如何将 ID 传递到 DetailsPage 吗?

【问题讨论】:

    标签: reactjs react-router


    【解决方案1】:

    我用它来访问我的组件中的 ID:

    <Route path="/details/:id" component={DetailsPage}/>
    

    在细节组件中:

    export default class DetailsPage extends Component {
      render() {
        return(
          <div>
            <h2>{this.props.match.params.id}</h2>
          </div>
        )
      }
    }
    

    这将在 h2 中呈现任何 ID,希望对某人有所帮助。

    【讨论】:

    • 太棒了!我错过了“.params”部分!谢谢!
    • 这应该是公认的答案,它更干净、更简单。
    • 这是一个更简单、更清晰的答案。但是,有一个限制。除了路由属性对象中已有的属性外,它不允许您传递任何其他属性。接受的答案确实如此。
    【解决方案2】:

    如果你想将 props 传递给路由中的组件,最简单的方法是使用 render,如下所示:

    <Route exact path="/details/:id" render={(props) => <DetailsPage globalStore={globalStore} {...props} /> } />
    

    您可以使用以下方式访问DetailPage 中的道具:

    this.props.match
    this.props.globalStore
    

    {...props} 是传递原始 Route 的 props 所必需的,否则你只会在 DetailPage 中得到this.props.globalStore

    【讨论】:

    • 但是为什么它不能按照我在询问中指定的方式工作?
    • 首先,您的代码错误。将组件放置在类似&lt;Route exact path="/details/:id" &gt;&lt;DetailsPage /&gt;&lt;/Route&gt; 的路由中与&lt;Route exact path="/details/:id" component={DetailsPage} /&gt; 不同。即使您访问了“/”,您的代码也会呈现 DetailsPage。第二,当你写&lt;DetailsPage foo={this.props}/&gt;时,this指的是null。这就是它不起作用的原因。
    • 这给出了一个错误Warning: [react-router] You cannot change &lt;Router routes&gt;; it will be ignored
    • 请打开一个新问题并在那里分享您的代码。
    • 请参考下面@Alexander Luna 的回答以获得更简单的解决方案。
    【解决方案3】:

    从带有钩子的 react-router v5.1 开始:

    import { useParams } from 'react-router';
    
    export default function DetailsPage() {
      const { id } = useParams();
    }
    

    https://reacttraining.com/blog/react-router-v5-1/

    【讨论】:

    • 虽然是最新的,但这仅适用于功能组件。
    【解决方案4】:

    使用渲染方法:

    <Route exact path="/details/:id" render={(props) => (
        <DetailsPage id={props.match.params.id}/>
    )} />
    

    您应该能够使用以下方式访问 id:

    this.props.id
    

    DetailsPage 组件内部

    【讨论】:

    • 这个顺便说一句也适用于组件方法:&lt;Route path="/..." component={props =&gt; &lt;DetailsPage id={props.match.params.id}/&gt;}/&gt;
    【解决方案5】:

    除了 Alexander Lunas 的回答... 如果您想添加多个参数,只需使用:

    <Route path="/details/:id/:title" component={DetailsPage}/>
    
    export default class DetailsPage extends Component {
      render() {
        return(
          <div>
            <h2>{this.props.match.params.id}</h2>
            <h3>{this.props.match.params.title}</h3>
          </div>
        )
      }
    }
    

    【讨论】:

      【解决方案6】:

      使用组件:

      <Route exact path="/details/:id" component={DetailsPage} />
      

      您应该可以使用以下方式访问id

      this.props.match.params.id
      

      DetailsPage 组件内部

      【讨论】:

      • 这很有趣。但是,为什么这是分开的,因为我想将变量向下传递给组件。 &lt;Route exact path="/details/:id" &gt; &lt;DetailsPage globalStore={globalStore} /&gt; &lt;/Route&gt; 现在传递 globalStore 不起作用。
      • @Dekel 我正在尝试做完全相同的事情,但出现错误。所以,我提出了一个新问题。链接:stackoverflow.com/questions/52652521/… 我正在尝试访问控制台中的 id,就这么简单。
      • 如果你使用'render'而不是'Route'上的'component',它会提供良好的性能
      【解决方案7】:

      另一种解决方案是在路由组件中使用状态和生命周期挂钩,并在&lt;Link /&gt; 组件的to 属性中使用搜索语句。搜索参数稍后可以通过new URLSearchParams()访问;

      <Link 
        key={id} 
        to={{
          pathname: this.props.match.url + '/' + foo,
          search: '?foo=' + foo
        }} />
      
      <Route path="/details/:foo" component={DetailsPage}/>
      
      export default class DetailsPage extends Component {
      
          state = {
              foo: ''
          }
      
          componentDidMount () {
              this.parseQueryParams();
          }
      
          componentDidUpdate() {
              this.parseQueryParams();
          }
      
          parseQueryParams () {
              const query = new URLSearchParams(this.props.location.search);
              for (let param of query.entries()) {
                  if (this.state.foo!== param[1]) {
                      this.setState({foo: param[1]});
                  }
              }
          }
      
            render() {
              return(
                <div>
                  <h2>{this.state.foo}</h2>
                </div>
              )
            }
          }
      

      【讨论】:

        【解决方案8】:

        这是打字稿版本。工作于"react-router-dom": "^4.3.1"

        export const AppRouter: React.StatelessComponent = () => {
            return (
                <BrowserRouter>
                    <Switch>
                        <Route exact path="/problem/:problemId" render={props => <ProblemPage {...props.match.params} />} />
                        <Route path="/" exact component={App} />
                    </Switch>
                </BrowserRouter>
            );
        };
        

        和组件

        export class ProblemPage extends React.Component<ProblemRouteTokens> {
        
            public render(): JSX.Element {
                return <div>{this.props.problemId}</div>;
            }
        }
        

        在哪里ProblemRouteTokens

        导出接口 ProblemRouteTokens { 问题ID:字符串; }

        【讨论】:

        • 谢谢你,这更好,更简单的作品很棒
        • 我可以确认它在 v5.1.2 中也适用于类组件
        【解决方案9】:

        如果您使用类组件,您最有可能使用 GSerjo 建议。通过&lt;Route&gt; props 将参数传递给您的目标组件:

        exact path="/problem/:problemId" render={props => <ProblemPage {...props.match.params} />}
        

        【讨论】:

          【解决方案10】:

          这适用于 react-router-dom v6(我强烈建议为此使用功能组件)

          react-router-dom 不断改变语法和规则有点痛苦。但是这里什么都没有。

          您可以同时使用useParamsuseSelector 来解决此问题

          import { useParams } from 'react-router';
          import { useSelector } from 'react-redux';
          
          const Component = () => {
          const { id } = useParams();                              //returns the :id
          const page = useSelector((state) => state.something[id]); //returns state of the page
          
          return <div>Page Detail</div>;
          }
          
          export default Component;
          

          但是,当您还有一个动作创建者并且您想将其作为 connect 函数中的道具传递时,问题仍然存在

          export const connect(mapStateToProps, mapDispatchToProps)(Component)
          

          由于我们使用的是useParams,它不会传递给我们创建的mapStateToProps

          const mapStateToProps = (state, ownProps) => {
          console.log(ownProps)   //wont recognize :id
          //hence
          return {
            someReducers: state.someReducers[id] //would return an error: 'id' is not defined
           };
          };
          

          另一方面,您不能完全忽略 connect 函数,因为您需要 mapDispatchToProps 才能使用您的组件。

          解决方法是自己创建一个高阶组件withRouter 函数。这是一个已弃用的 react-router-dom 助手。

          //make this
          import { useParams, useLocation, useNavigate } from 'react-router';
          import { connect } from 'react-redux';
          import { yourActionCreator } from '../actionCreator';
          
          const withRouter = (Child) => {
          return (props) => {
           const location = useLocation();
           const navigation = useNavigate();
           const params = useParams();
           return (
             <Child
             {...props}
             params={params}
             navigate={navigate}
             location={location}
             />
            );
           };
          };
          
          const Component = () => {
          // your component...
          return <div> Page Detail </div>
          };
          
          export mapStateToProps = (state, ownProps) => {
          console.log(ownProps)     // would contain the :id params
          return {
          //something
           }
          };
          
          const mapDispatchToProps = {
          yourActionCreator
          }
          
          export withRouter(connect(mapStateToProps, mapDispatchToProps)(Component));
          

          【讨论】:

            【解决方案11】:

            试试这个。

            <Route exact path="/details/:id" render={(props)=>{return(
                <DetailsPage id={props.match.params.id}/>)
            }} />
            

            在详情页面试试这个...

            this.props.id
            

            【讨论】:

              猜你喜欢
              • 2017-10-24
              • 2017-09-14
              • 2015-12-30
              • 2023-01-24
              • 1970-01-01
              • 2019-09-29
              • 2017-02-13
              • 2015-07-12
              • 2016-10-14
              相关资源
              最近更新 更多