【问题标题】:change classname of element based on route in react router根据反应路由器中的路由更改元素的类名
【发布时间】:2021-04-27 13:14:03
【问题描述】:

我已经在文档和各种论坛中搜索了一段时间,但似乎找不到任何 React Router 组件或解决方法可以实现这样的功能。

与我们拥有NavLink 组件的方式类似,React Router 规范中是否有任何组件可以用于类似程度地更改classNames 上的div路由匹配时的元素?

例如:

<Element 
    exact to={["/one", "/two"]} 
    className="default-class" 
    activeClassName="open"
>
    <ChildComponent />
</Element>

这定义了,当用户在/two/two 上时,它将呈现:

<div class="default-class open">
     <!-- child components !-->
</div>

【问题讨论】:

    标签: javascript reactjs react-router


    【解决方案1】:

    如果我理解正确,您正在尝试根据路由定义类名。您可以使用 react-router 提供的 useLocation 钩子在组件内部进行操作

    import {useLocation} from 'react-router-rom'
    
    const location = useLocation();
    
    
    if(location =='/one'){
     return SOMETHING
    }
    else{
        return SOMETHING ELSE
    }
    
    

    【讨论】:

      【解决方案2】:

      我查看了source code 中的NavLink 组件。我的第一个想法是复制并粘贴该代码并将其转换为withActiveStyling HOC。不幸的是,它使用了一些不是从“react-router-dom”包中导出的内部组件,因此它不仅仅是复制和粘贴。但我们可以使用该来源作为模板。

      此 HOC 接受 NavLink 的所有属性,对 to 进行了一些更改:它只接受 stringarray 或字符串,但不接受函数。

      如果当前位置与to 位置匹配,它会编辑Wrapped Component 的属性classNamestyle 以包含activeClassName 和/或activeStyle。道具exactstrictsensitive将用于判断是否匹配。

      const withActiveStyling = ( WrappedComponent ) => {
        return (props) => {
          const {
            activeClassName = "active",
            activeStyle,
            className: classNameProp,
            isActive: isActiveProp,
            location: locationProp,
            style: styleProp
          } = props;
          const location = useLocation();
          const currentLocation = locationProp || location;
          // get a match object (or null) based on the whether the current location matches the props (to, exact, etc)
          const match = matchPath(currentLocation.pathname, {
            ...props,
            path: props.to
          });
      
          const isActive = !!(isActiveProp
            ? isActiveProp(match, currentLocation)
            : match);
      
          const className = isActive
            ? joinClassnames(classNameProp, activeClassName)
            : classNameProp;
          const style = isActive ? { ...styleProp, ...activeStyle } : styleProp;
      
          return <WrappedComponent {...props} style={style} className={className} />;
        };
      };
      

      CodeSandbox Link 带有打字稿注释

      【讨论】:

        猜你喜欢
        • 2020-10-27
        • 2018-02-10
        • 2017-07-16
        • 2017-07-29
        • 1970-01-01
        • 2016-10-26
        • 1970-01-01
        • 2021-12-21
        • 2017-09-03
        相关资源
        最近更新 更多