【问题标题】:Is there a function in react to hide a component based on the website path?是否有根据网站路径隐藏组件的功能?
【发布时间】:2021-01-26 01:55:40
【问题描述】:

在我的反应应用程序中,我目前有这个:

<Router>
    <div class Name="App">
      <Route path="/" exact component={PersonList} />
      <Route path="/rules" exact component={RulesPage} />
      <Route path="/roles" exact component={RolesPage} />
      <Route path="/test" exact component={Test} />
      <Footer />
    </div>
  </Router>

但是,如果路由路径是“/test”,我希望隐藏页脚元素 会比写的干净很多:

<Route path="/roles" exact component={Footer} />
<Route path="/rules" exact component={Footer} />
<Route path="/" exact component={Footer} />

如果有人知道这样做的功能,将不胜感激。

【问题讨论】:

标签: javascript reactjs jsx


【解决方案1】:

在您的 Footer 组件中,您可以检查 window.location.pathname 是否包含 /test 并返回 null

【讨论】:

  • ``` if(window.location.pathname.includes === "/test"){ return( null ) } ``` 我添加了这个,仍然显示在网站上
【解决方案2】:

您可以创建一个高阶组件来呈现带有页脚的组件,然后您可以在除/test 之外的所有路径上呈现该高阶组件。

高阶组件只接受一个应该与Footer 组件一起显示的组件,并返回另一个组件,该组件仅与Footer 组件一起呈现包装的组件。

function WithFooter(WrappedComponent) {
  const EnhancedComponent = (props) => {
    return (
      <>
        <WrappedComponent {...props} />
        <Footer />
      </>
    );
  };

  return EnhancedComponent;
}

之后,不再导出PersonList组件,而是需要导出调用WithFooter高阶组件返回的组件,如下图:

function PersonList() {
  ...
}

export default WithFooter(PersonList);

您也需要对应该使用Footer 呈现的其他组件执行相同操作。

高阶组件全部设置完毕,您的路线定义无需更改:

<Router>
   <Route path="/" exact component={PersonList)} />
   <Route path="/rules" exact component={RulesPage} />
   <Route path="/roles" exact component={RolesPage} />
   <Route path="/test" exact component={Test} />
</Router>

另一种解决方案是在使用window.locationuseParams() 提供的react-router-dom 钩子检查URL 后有条件地渲染Footer 组件,但useParams() 仅在您的组件使用react router 渲染时才有效。在您的情况下,您将需要window.location

【讨论】:

  • withFooter 未定义
  • 你需要写withFooter高阶组件,它不是内置组件
  • 如果您不清楚如何实现高阶组件并使其全部工作,我已经添加了有关如何实现高阶组件和其他更改的更多细节需要做的。
【解决方案3】:

如果您不熟悉 HOC 模式,另一种选择是将 &lt;Footer/&gt; 组件仅呈现在那些需要它的组件内部,而不是在顶层。

【讨论】:

    【解决方案4】:

    您可以检查页脚内的路线详细信息并根据您的情况进行渲染。如果您使用钩子,React Router >= 5.1 附带 useRouteMatch。如果您使用的是类(或较旧的 React 路由器),则需要使用 withRouter High-Order Component。您也可以自己检查窗口位置,但我建议您使用通过 react router 已经可用的工具。

    钩子示例

    function Footer() {
      const match = useRouteMatch("/test");
    
      // You can also use match.isExact when it's avaible to narrow
      // the check down to specifically "/test" but still keep urls
      // such as "/test/some/other/path"
      if (match /*&& match.isExact*/) return null;
    
      return <footer>This is the footer</footer>;
    }
    

    高阶组件示例

    class FooterWithRouter extends Component {
      render() {
        if (this.props.location.pathname === "/test") {
          return null;
        }
    
        return <footer>This is the footer</footer>;
      }
    }
    const Footer = withRouter(FooterWithRouter);
    

    用于代码示例的 CodeSandbox https://codesandbox.io/s/runtime-cdn-v7icj

    https://v7icj.csb.app/ https://v7icj.csb.app/test

    【讨论】:

    • 使用useRouteMatch 钩子会起作用,但我不推荐它,原因有两个: 1. Footer 组件不必关心它在哪个路由上渲染或不渲染。 2. 每次出现Footer 不应该渲染的新路由时,您都需要更新Footer 组件。
    • @Yousaf 公平积分。有人可能会争辩说,使用 HOC,每个组件现在都间接关心页脚,并且每个需要页脚的新组件都需要引用 HOC,从而导致更多的间接关系。至于页脚不知道当前路线。当然可以,但是谁的责任?应用程序?如果是这种情况,请将逻辑提升到应用程序中并保留页脚。
    猜你喜欢
    • 1970-01-01
    • 2018-05-09
    • 2017-02-03
    • 2013-04-17
    • 2020-05-29
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多