web-dev-qa-db-ja.com

react-router v4でアクティブリンクをスタイルするにはどうすればよいですか?

React-router v3では、アクティブリンクをスタイルするactiveStyleとactiveClassNameがありました

このようなことができます

  <div id="tags-container">
    {tags.map(t =>
      <Link
        className="tags"
        activeStyle={{ color: 'red' }}
        to={t.path}
      >
        {t.title}
      </Link>
    )}
  </div>

V4で同じことができる方法を知りたいですか?

30

リンクの代わりにNavLinkを使用します。文書化されていませんが、期待どおりの動作です。 https://github.com/ReactTraining/react-router/issues/4318

2017年5月17日更新:

https://reacttraining.com/react-router/web/api/NavLink

26
Sergey Reutskiy

react-router v4のNavLinkで実行できます

 <div id="tags-container">
   {tags.map(t =>
     <NavLink
       className="tags"
       activeStyle={{ color: 'red' }}
       to={t.path}
     >
       {t.title}
     </NavLink>
   )}
 </div>
13
Gapur Kassym

リンクをクリックしてルートが変更されたときに適切に更新されない以外はNavメニューが機能する問題が発生しているが、を押すと正常に機能するF5、これを行うことができます:

これはおそらく、shouldComponentUpdate関数にconnect Lifecycleメソッドを持つReduxを使用しているために発生しています。おそらく、Navコンポーネントはconnectでラップされています。これはすべて良いです。 shouldComponentUpdateはあなたの人生を台無しにしているものです。

修正するには、ルーターをmapStateToProps関数に入れるだけです:

// This lets shouldComponentUpdate know that the route changed,
// which allows the Nav to re-render properly when the route changes, woot!
const mapStateToProps = (state) => {
  return {
    router: state.router,
  }
}

// or, if you prefer pro style destructure shorthand:
const mapStateToProps = ({ router }) => ({ router })

state.routerがどこから来たのかよくわからない場合、それはレデューサーを結合したファイルから来ており、次のようなものが表示されます:

import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux'
import authReducer from './components/auth/auth_reducer'

export default combineReducers({
  router: routerReducer,
  auth: authReducer,
})

以下は、かなりバラエティに富んだNav LinkのHTMLとCSSです。

HTML

<ul id="Nav_menu">
  <li>
    <NavLink
      to="/home"
      className="Nav_link"
      activeClassName="activeRoute"
      activeStyle={{ color: 'teal' }}
    >
      HOME
    </NavLink>
  </li>
  <li>
    <NavLink
    to="/products"
    className="Nav_link"
    activeClassName="activeRoute"
    activeStyle={{ color: 'teal' }}
    >
      PRODUCTS
    </NavLink>
  </li>
</ul>

注:"/"にリンクしている場合は、exact propをNavLinkに配置します。

CSS

#Nav_menu {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 100%;
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.Nav_link:link {
  color: #fff;
  font-size: 1.6rem;
  line-height: 1.6rem;
  text-decoration: none;
}
.Nav_link:visited {
  color: #fff;
}
.Nav_link:hover {
  color: yellow;
}
.Nav_link:active {
  color: teal;
}

.activeRoute {
  background-color: yellow;
  border-bottom: 0.4rem solid teal;
  cursor: not-allowed;
}

HTMLマークアップのactiveStyleに注意してください。これが、アクティブなルート/リンク上のテキストの色を変更できる唯一の方法でした。 activeRoute CSSクラスにcolor: teal;を入れたときに機能しませんでした。これを別のタブで開きます: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/NavLink.md

remの代わりにpxを使用した理由がわからない場合。これは、Webアクセシビリティとベースfont-size: 10px;を調査する絶好の機会です。

健康を維持し、楽しんでください。

6
agm1984

React-router v4 custom link documentation からのこの例は、あなたがそれを達成するのに役立ちます:

const OldSchoolMenuLink = ({ label, to, activeOnlyWhenExact }) => (
  <Route path={to} exact={activeOnlyWhenExact} children={({ match }) => (
    <div className={match ? 'active' : ''}>
      {match ? '> ' : ''}<Link to={to}>{label}</Link>
    </div>
  )}/>
);

したがって、あなたの場合、次のコンポーネントを作成できます。

const CustomLink = ({ activeStyle, children, className, to, activeOnlyWhenExact }) => (
  <Route path={to} exact={activeOnlyWhenExact} children={({ match }) => (
    <Link to={to} className={className} style={match && activeStyle}>{children}</Link>
  )}/>
);

そして、それを次のように使用します:

  <div id="tags-container">
    {tags.map(t =>
      <CustomLink
        className="tags"
        activeStyle={{ color: 'red' }}
        to={t.path}
      >
        {t.title}
      </Link>
    )}
  </div>
3
glennreyes

@ agm1984's answer の展開:NavLinksのソリューションは、react-router-reduxからrouterReducerを使用していたスタイルを正しく更新していませんが、私にとってはうまくいきませんでした。代わりに、問題はconnectラッパーがshouldComponentUpdateを使用し、NavLinksを含むコンポーネントの再レンダリングを妨げることであることがわかりました。

私の状況での正しい解決策は、以下に示すように、4番目のパラメーターとしてconnectにオプションオブジェクトを渡すことでした。

export default connect(mapStateToProps, null, null, { pure: false })(NavItems);
3
MrSegFaulty

すべて同じです。ただし、react-router-dom v4はLinkNavLinkに置き換えます

import { NavLink as Link } from 'react-router-dom';も問題ありません。注:Navlinksはデフォルトでアクティブであるため、a:activeまたはactiveStyle={{color: 'red'}}のスタイルを設定できます

1