Material-ui: [MenuItem]メニュー項目内のリンク

作成日 2015年01月06日  ·  43コメント  ·  ソース: mui-org/material-ui

こんにちは、私はメニュー項目の現在の実装を見ていて、実際のリンクがないことに気づきました(つまり、html <a>タグ)。 その結果、たとえば、ナビゲーションバーでも実際のリンクはなく、他のページへの遷移はonclickイベントを介して管理されます。

特にサーバー側でレンダリングされたページを考えると、リンクがあると改善されると思います。

これは理にかなっていると思いますか、それともこの方向に進まない特別な理由がありますか?

v0.x

最も参考になるコメント

containerElement小道具を使用してください!

見る:
http://stackoverflow.com/questions/32106513/material-ui-menu-using-routes/34507786#34507786

<MenuItem
  containerElement={<Link to="/profile" />}
  primaryText="Profile"
  leftIcon={
    <FontIcon className="material-icons">people</FontIcon>
  } />

全てのコメント43件

これについても気になります。 アプリケーションでサーバー側のレンダリングを使用しています。これは調査する必要があります。

href属性を持つアンカー要素を使用すると、アクセシビリティが向上し、ユーザーが慣れ親しんだブラウザーの動作を使用できるようになります(例:⌘-クリックして新しいタブで開きます)。

+1

+1

+1

+1

+1

+1

+1

@ecesenaこれは新しいMenuItemコンポーネントの問題であると思いますか? ここを参照してMenuItem <a>..</a>で囲むことができますね?

これは@ shaurya947が提案したことで可能です。

私はLeftNavでMenuItemsを次のように使用しようとしています:

        let menuItems = (
            <div>
                <MenuItem primaryText="Doors"           leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} /></a>
                <MenuItem primaryText="Load"           leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
                <MenuItem primaryText="Notes"           leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
                <MenuItem primaryText="Alerts"          leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
                <MenuItem primaryText="Admin"           leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
            </div>
        );

        return (
            <LeftNav
                ref="leftNav"
                docked={false}
                onChange={this._onLeftNavChange}
            >
                {menuItems}
            </LeftNav>
        )

<a><MenuItem>タグの周りにラップすると、警告validateDOMNesting(...): <a> cannot appear as a descendant of <a>. See MainLayout > a > ... > MenuItem > ListItem > EnhancedButton > a"スローされます

出力のReact検査を行うと、次のようになります。

<a href="/">
    <MenuItem..>
        <ListItem..>
            <div>
                <EnhancedButton..>
                    <a>
                        <TouchRipple ..>
                    </a>
                </EnhancedButton>
            </div>
        </ListItem>
    </MenuItem>
</a>

<a>要素をネストすることは不快です。

<MenuItems>は、Button宣言内に<a>要素を生成します。生成された<EnhancedButton>内にhref属性を設定するために、 MenuItemからどの小道具が使用されますか?

MenuItemオブジェクトをLeftNavの小道具として使用すると、リンクが機能しますが、この方法で左/右のアイコンを追加する方法を理解できませんでした。

すなわち:

let menuItems = [
         { route: '/load_areas/'+ this.state.area + '/doors', text: 'Doors' },
         { route: '/load_areas/'+ this.state.area + '/trailer_loads', text: 'Load' },
         { route: 'notes', text: 'Notes' },
         { route: 'alerts', text: 'Alerts' },
         { route: 'admin', text: 'Admin' }
         ];

<LeftNav
                ref="leftNav"
                docked={false}
                menuItems={menuItems}
                onChange={this._onLeftNavChange}
            />

これは別の問題です。開いてください。ラベルを付けてマイルストーンに追加できます。tnx:grin:

containerElement小道具を使用してください!

見る:
http://stackoverflow.com/questions/32106513/material-ui-menu-using-routes/34507786#34507786

<MenuItem
  containerElement={<Link to="/profile" />}
  primaryText="Profile"
  leftIcon={
    <FontIcon className="material-icons">people</FontIcon>
  } />

EnhancedButtonの小道具linkButton EnhancedButtonは非推奨になりました。 hrefプロパティが提供されている場合、LinkBut​​tonは不要になりました。 v0.16.0で削除されます。

例えば:

<MenuItem primaryText="Primary Text" href="/your/link" />

hrefはページをリロードします。 反応ルーターを使用したい場合はどうですか

@cezarneagaはhref="#/your/link"試してください

<MenuItem
  containerElement={<Link to="/profile" />}
.../>

ドキュメントには、 linkButtonも入力する必要があると記載されています。 これを削除すると、エラーなしで機能します。

@DaxChen 2016年12月のstackoverflowの更新された回答(非常に最近の

<Drawer
  docked={false}
  width={300}
  onRequestChange={this.closeDrawer}
  open={this.state.open}>
  <AppBar title="Title"
 />
  <MenuItem primaryText="home" containerElement={<Link to="/home" />} />
</Drawer>

containerElementは機能しますが、ドキュメント化されていないため、このスレッドは今のところ公式ドキュメントとして機能する必要があると思います。 ありがとう!

こんにちは@Faolain

返信が遅くなって本当に申し訳ありません...
create-react-appを使用してクリーンなアプリでコーディングしてみましたが、すべて正常に機能しているように見えましたか?!
react-router別の方法で構成したのでしょうか、それともバージョンが違うのでしょうか。

とにかく、ここにレポの例ライブデモがあります。

それでも問題の原因が見つからない場合は、再現するためのサンプルリポジトリを提供できますか?

上記のソリューションはいずれもSafariとiOSでは機能しませんでした。 これがreact-router回避策として私がしたことです

          <MenuItem
            onTouchTap={() => {
              this._yourMethod()
              browserHistory.push('/howItWorks')
            }}
            primaryText="Menu Link"
          />

@janzenzは、この例がブラウザで機能していませんか?

macOSのSafariとiOSのSafariで試してみましたが、すべて動作します。 これはあなたのために働いていませんか?

回避策は機能しますが、SEOが悪化する可能性があり、リンクプレビューやオプションクリックなどのネイティブな動作が失われ、新しいタブで開きます。

@DaxChenは洞察に感謝します。 私の問題があなたの最初のリンクに関連しているかどうかはわかりません。 私はすでに2つ目を試しましたが、 onTouchTapプロップを追加すると、 <Link />は機能しなくなります。

@janzenz前の例でonTouchTap小道具を追加しましたが、それでも機能します。
設定がどこか違うのかわからない...😢
更新されたコードをチェックして

@DaxChenバージョン~0.16.0 material-uiを使用しているようです。 最新の~0.17.0を試し、それでも問題がないかどうかを確認しましたか?

@janzenz私は古いバージョンを使用していましたが、最新の0.17.4更新されましたが、それでも機能します。

Touché! おそらく私のセットアップ。 @DaxChenを確認していただき、ありがとうございます。実際の問題が見つかった場合は、このスレッドに戻ります。

@DaxChen 、私はあなたが私に与えた例を試しましたが、失敗します

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in. Check the render method of `EnhancedButton`.
    at invariant (invariant.js:44)
    at ReactCompositeComponentWrapper.instantiateReactComponent [as _instantiateReactComponent] (instantiateReactComponent.js:74)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:367)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at mountComponentIntoNode (ReactMount.js:104)
    at ReactReconcileTransaction.perform (Transaction.js:140)
    at batchedMountComponentIntoNode (ReactMount.js:126)
    at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:140)
    at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
    at Object.batchedUpdates (ReactUpdates.js:97)
    at Object._renderNewRootComponent (ReactMount.js:320)
    at Object._renderSubtreeIntoContainer (ReactMount.js:401)
    at Object.render (ReactMount.js:422)
    at Object.<anonymous> (index.js:36)
    at __webpack_require__ (bootstrap e3e2367…:555)
    at fn (bootstrap e3e2367…:86)
    at Object.<anonymous> (bootstrap e3e2367…:578)
    at __webpack_require__ (bootstrap e3e2367…:555)
    at bootstrap e3e2367…:578
    at bootstrap e3e2367…:578

私のコードはhttps://github.com/hhimanshu/spicyveggie/tree/cards($#$ cardsブランチ)で入手できます

何が違うのかわかりませんが、うまくいきません

@janzenz
私も試してみましたbrowserHistory.push('/howItWorks')輸入import browserHistory from 'react-router-dom'が、得たundefuned

@Oduig
#/your/linkを試しましたが、どこにも行きません
/your/linkを試しましたが、ページがリロードされ、 Material-UIからDrawer失われます。

これらのことはどれも私にはうまくいきませんでした。 私のコードはhttps://github.com/hhimanshu/spicyveggie/tree/cards($#$ cardsブランチ)で入手できます。具体的なコミットはhttps://github.com/hhimanshu/spicyveggie/commit/844b7b7cddf9102995cd2680a783df3b6ef48537です

@hhimanshuこの行をに変更します

import { Link } from 'react-router-dom'

MDNの詳細

@DaxChen 、ありがとう。 それでした。 ただし、ページが{<Link to="/menu"/>}で読み込まれる場合は、ページ全体が読み込まれ、 Drawerはなくなります。

screen shot 2017-04-24 at 1 54 23 pm

@hhimanshuは、 \menuルートAppはレンダリングされません。

MenuSummaryAppまたはいくつかのレイアウトコンポーネント内にネストし、それぞれの子を渡します。

react-devtoolsを使用して、レンダリングされたコンポーネントの階層とその状態を確認できます。

これはmaterial-uiとは関係ありません。詳しくは、react-routerのチュートリアル/ドキュメントをご覧ください。

+1

Reactルーターによって処理されたリンクと処理されていないリンクの回避策。


ターゲットリンクがReactRouterによって処理される場合

MenuItemLink.js

import React from 'react';
import { MenuItem } from 'material-ui/Menu';
import { Route } from 'react-router-dom';

class MenuItemLink extends React.Component {
  render() {
    const {
      to, also,
      ...rest
    } = this.props;

    return (
      <Route
        render={({ history, location }) => (
          <MenuItem
            onClick={() => {
              history.push(to);
              if (typeof also === 'function') {
                also();
              }
            }}
            {...rest}
          />
        )}
      />
    );
  }
}
MenuItemLink.muiName = 'MenuItem';
export default MenuItemLink;

サンプルコード:

import MenuItemLink from './MenuItemLink';
<Menu ... >
        <MenuItemLink to="/users"
          also={this.handleRequestClose}>Users</MenuItemLink>
</Menu>

ターゲットリンクがReactRouterによって処理されない場合、つまり、リクエストはAPIサーバーなどに転送されます

onClick関数:

    function facebookLoginRedirect () {
      if (window) window.location.href = "/api/auth/facebook"
      return true;
    }

サンプルコード:

<MenuItem onClick={ facebookLoginRedirect }>Login with Facebook</MenuItem>

他の誰かがそれに遭遇した場合に備えて、私はこれに追加するつもりです。

v3.4では、次のようにこれを実現できます。

import { Link } from 'react-router-dom';
import MenuItem from '@material-ui/core/MenuItem';

...

<MenuItem component={Link} to="/your-path">...</MenuItem>

メニューレイアウトを壊さずに私のために働いた唯一の解決策は次のとおりでした:
`` `javascript


通知



プロフィール


メニューレイアウトを壊さずに私のために働いた唯一の解決策は次のとおりでした:

<MenuList>
  <Link to='/your-path' style={{ textDecoration: 'none' }}>
    <MenuItem>
      Notifications
     </MenuItem>
  </Link>
  <Link to='/your-path' style={{ textDecoration: 'none' }}>
    <MenuItem>
      Profile
     </MenuItem>
  </Link>
</MenuList>

@eladlevyこれは、セマンティクスが不十分なHTMLになります。

<ul>
  <a><li/></a>
  <a><li/></a>
</ul>

誰かに役立つ場合に備えて、これをここに残しておきます(v3.9.0を実行)。 react-router-dom <Link>のメニューとして機能するには、 <Select>が必要でした。 各リンクは言語設定に対応しているため、ドロップダウンにはクエリパラメータからの現在の言語の値が表示されます。

<Select value={currentLanguage}>
  {languages.map(language => (
    <ListItem
      button
      component={btnProps => (
        <Link
          to={ `/things?lang=${ language }` }
          {...btnProps as any}
        />
      )}
      value={language}
      key={language}
    >
      {language}
    </ListItem>
  ))}
</Select>

これは、最小限のTypeScriptキャストが必要であり、マテリアルUIと一貫性のあるビジュアルを維持することができた最もクリーンなソリューションでした。

@goyneyには解決策があります、ありがとう

他の誰かがそれに遭遇した場合に備えて、私はこれに追加するつもりです。

v3.4では、次のようにこれを実現できます。

import { Link } from 'react-router-dom';
import MenuItem from '@material-ui/core/MenuItem';

...

<MenuItem component={Link} to="/your-path">...</MenuItem>

実用的でクリーンなソリューション、ありがとう❤️

外部リンクの場合は、 component="a"を使用する必要がありますが、 <li> MenuItemを囲みます。

<MenuList>
    <li>
        <MenuItem
            component="a"
            href="https://google.com"
            target="_blank"
        >Google</MenuItem>
    </li>
</MenuList>

これにより、次のHTMLが生成されます。

<ul class="MuiList-root MuiList-padding" role="menu" tabindex="-1">
    <li>
        <a class="[...]" tabindex="-1" aria-disabled="false" role="menuitem" href="https://google.com" target="_blank">Google</a>
    </li>
</ul>

ポップアップメニューがあり、

import {Link} from'react-router-dom ';
'@ Material-ui / core / MenuItem'からMenuItemをインポートします。

\\

リンクをクリックすると/ your-pathページが表示されますが、ポップアップメニューを閉じるにはどうすればよいですか?

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

finaiized picture finaiized  ·  3コメント

reflog picture reflog  ·  3コメント

sys13 picture sys13  ·  3コメント

ryanflorence picture ryanflorence  ·  3コメント

rbozan picture rbozan  ·  3コメント