【问题标题】:Set Material-UI tab active based on visited route根据访问的路线设置 Material-UI 选项卡处于活动状态
【发布时间】:2017-01-25 09:09:10
【问题描述】:

在我的新 react-redux 应用程序中(我是新手),我使用 Material-UI 并在我的网络应用程序中添加了 material-ui 选项卡。这些选项卡旨在更改我使用以下代码实现的选择后的 URL。

function handleActive(tab) {
    browserHistory.push(tab.props['data-route']);
}

当我手动访问路线而不是单击选项卡时,我希望我的选项卡显示选定的选项卡指示器。我现在无法弄清楚。任何人都可以通过 react 或 redux 向我建议一种方法吗?如果我的问题不清楚,请告诉我。

更新

我的组件中的代码render()。组件中没有其他内容。

render() {
    function handleActive(tab) {
        browserHistory.push(tab.props['data-route']);
    }

    return (
        <Paper>
            <Toolbar className="navbar">
                <ToolbarGroup>
                    <Link to="/" style={{ textDecoration: 'none' }}>
                        <ToolbarTitle style={this.styles.title} text="Test App" />
                    </Link>
                </ToolbarGroup>
                <ToolbarGroup className="tab-container">
                    <Tabs className="tabs">
                        <Tab data-route="/" onActive={handleActive} className="tab" label="Route A" />
                        <Tab data-route="/routeB" onActive={handleActive} className="tab" label="Route B" />
                        <Tab data-route="/routeC" onActive={handleActive} className="tab" label="Route C" />
                        <Tab data-route="/routeD" onActive={handleActive} className="tab" label="Route D" />
                    </Tabs>
                </ToolbarGroup>
            </Toolbar>
        </Paper>
    );
}

【问题讨论】:

  • 你能发布你的组件的完整代码吗?
  • @RandomUser 添加了代码。

标签: reactjs react-router react-redux material-ui


【解决方案1】:

我怀疑解析 url 是否是个好主意。也许在&lt;Route&gt;onEnter 属性中从路由器调度操作中控制标签索引更好?

假设您有 2 条路线:

<Route path='sign_in' component={AuthenticationWrapper} onEnter={() => { store.dispatch(changeTab(0)) }} />
<Route path='sign_up' component={AuthenticationWrapper} onEnter={() => { store.dispatch(changeTab(1)) }} />

动作创建者:

changeTab = (index) => {
  return { type: AUTH_TAB_CHANGE, index }
}

减速机:

authTab = (state = 0, action = {}) => {
  switch (action.type) {
    case AUTH_TAB_CHANGE:
      return action.index
    default:
      return state
  }
}

组件:

class AuthenticationWrapper extends Component {
  constructor(props) {
    super(props)

    this.handleSignIn = this.handleActive.bind(this, '/sign_in')
    this.handleSignUp = this.handleActive.bind(this, '/sign_up')
  }

  handleActive(url) {
    browserHistory.push(url)
  }

  render() {
    const { authTab, changeTab } = this.props

    return (
      <Tabs index={authTab} onChange={changeTab}>
        <Tab label='Sign In' onActive={this.handleSignIn}>
          <SignInForm />
        </Tab>
        <Tab label='Sign Up' onActive={this.handleSignUp}>
          <SignUpForm />
        </Tab>
      </Tabs>
    )
  }
}

const mapStateToProps = ({ authTab }) => {
  return {
    authTab
  }
}

export default connect(mapStateToProps, {
  changeTab,
})(AuthenticationWrapper)

这种方法既适用于访问不同的网址,也适用于通过点击它们而不刷新页面来更改标签。

【讨论】:

    【解决方案2】:

    虽然有几种方法可以做到这一点,由于您使用的是 React 组件类, 可以加componentWillMount

    componentWillMount() {
    
      let urlPath = window.location.pathname;
      let currentTab = urlPath.split('/').pop();
      // you can add more validations here
      this.setState({ activeTab: currentTab || 'default' });
    
    }
    

    并在您的 render 方法中,将 &lt;Tabs className="tabs"&gt; 更改为

    <Tabs
      className="tabs"
      value={this.state.activeTab}
      >
        <Tab value="default" data-route="/" onActive={handleActive} className="tab" label="Route A" />
        <Tab value="routeC" data-route="/routeC" onActive={handleActive} className="tab" label="Route C" />
        ...
    

    我不知道这是否是我们应该为value 设置Tab.. 的方式,但请尝试一下。

    它应该可以工作。

    我在这里使用setState而不是redux,因为使用组件状态没有任何问题,只要这是唯一需要知道哪个选项卡当前处于活动状态的组件。您可以轻松地将其更改为使用redux 不过。

    【讨论】:

    • 我怀疑解析 url 是否是个好主意。也许最好从&lt;Route&gt;onEnter 属性中的路由器调度操作中控制标签索引?请参阅下面的代码。
    • @ktaras 虽然您可能是对的,但这也不是一个坏主意。这一切都取决于用户的要求。如果这是唯一关心当前选项卡的组件,则无需将其保存在redux store 中,也无需使用react-router 中间件,因为这将增加组件的依赖关系,用户可以轻松使用redux,@ 987654336@、middlewarespure functions 或所有的组合。
    【解决方案3】:

    要实现这一点,您需要做几件事以确保您可以在标签所在的页面中捕获 url。这是您应该做的:

    • 在渲染最高组件时,确保在 index html 的 div id 中渲染了 &lt;Router history={browserHistory} routes={routes} /&gt;。看来你正在这样做,因为你有 browserHistory 工作。
    • 在您的路由中,请确保您有嵌套路由,以便在父组件中传递 this.props.children,以便在 url 中反映的子组件中有 /path/to/comp。同样,您可能也已进行了此设置。
    • 现在,您需要按照此处http://www.material-ui.com/#/components/tabs 中的说明为您的选项卡和选项卡组件添加价值。值将根据为选项卡选择的选项指定哪个选项卡处于活动状态,因此&lt;Tabs className="tabs" value={this is where your this.props.params.name_of_changing_route}&gt; 或者如果您有 react-router 2.4.0,您可以使用 withRouter 包装您的组件,然后您可以访问参数、位置和路由。

    【讨论】:

      猜你喜欢
      • 2020-01-19
      • 2016-06-30
      • 2017-01-21
      • 1970-01-01
      • 2021-11-26
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      • 2020-05-21
      相关资源
      最近更新 更多