React.js-路由到不同的选项卡

时间:2018-07-06 06:01:44

标签: reactjs redirect react-router

我的项目中有一个HeaderComponent和一个BodyComponent。 这是TabComponent中的HeaderComponent

TabComponent

import React, {Component} from 'react'
import Context from '../../provider'
import {Nav, NavItem, NavLink} from 'reactstrap'
import {Redirect} from 'react-router-dom'
import classnames from 'classnames'

export default class TabComponent extends Component {
    render() {
        return (
            <Context.Consumer>
                {context => (
                    <Nav tabs color='primary'>
                        <NavItem>
                            <NavLink
                                className={classnames({ active: context.activeTab === '1' })}
                                onClick={() => { context.toggleTab('1'); }}
                            >
                            Home
                            </NavLink>
                        </NavItem>
                        <NavItem>
                            <NavLink
                                className={classnames({ active: context.activeTab === '2' })}
                                onClick={() => { context.toggleTab('2'); }}
                            >
                            Popular
                            </NavLink>
                        </NavItem>
                        <NavItem>
                            <NavLink
                                className={classnames({ active: context.activeTab === '3' })}
                                onClick={() => { context.toggleTab('3'); }}
                            >
                            All
                            </NavLink>
                        </NavItem>                
                    </Nav>
                )}
            </Context.Consumer>
        )
    }
}

BodyComponent

import React, {Component} from 'react'
import Context from '../provider'
import SwitchTab from './OtherComponents/SwitchTab'
import { BrowserRouter, Route, Redirect } from "react-router-dom";

export default class BodyComponent extends Component {
    render() {
        return (
            <Context.Consumer>
                {context => {
                    return (
                        <React.Fragment>
                            <BrowserRouter>
                                <React.Fragment>
                                    <Route exact path='/' render={() => <Redirect to='/home/' /> } />
                                    <Route eaxt path='/home/' render={() => context.activetab='1'} />
                                    <Route eaxt path='/popular/' render={() => context.activetab='2'} />
                                    <Route eaxt path='/all/' render={() => context.activetab='3'} />
                                </React.Fragment>
                            </BrowserRouter>
                            <SwitchTab />
                        </React.Fragment>
                    )
                }}
            </Context.Consumer>
        )
    }
}

这是我的 provider.js ,其中包含Context

import React, {Component} from 'react';

const Context = React.createContext();

class Provider extends Component {
  state = {

    loggedIn: false,
    username: '',
    password: '',
    loginModalOpen: false,
    signupModalOpen: false,
    navbarOpen: false,
    activeTab: '3',

    toggleLoggedIn: () => {
      this.setState({loggedIn: !this.state.loggedIn});
    },

    toggleLoginModal: () => {
      this.setState({loginModalOpen: !this.state.loginModalOpen});
    },

    toggleSignupModal: () => {
      this.setState({signupModalOpen: !this.state.signupModalOpen});
    },


    toggleNavbar: () => {
      this.setState({navbarOpen: !this.state.navbarOpen})
    },

    toggleTab: (tab) => {
      if(this.state.activeTab !== tab) {
        this.setState({activeTab: tab});
      }
    }
  }

  render() {
    return (
        <Context.Provider value={this.state}>
            {this.props.children}
        </Context.Provider>
    )
  }
}

export {Provider};
export default Context;

而且,这是我的SwitchTab

import React, {Component} from 'react'
import Context from "../../../provider";
import { Container, TabContent, TabPane } from "reactstrap";
import Home from '../../Content/Home'
import Popular from '../../Content/Popular'
import All from '../../Content/All'

export default class SwitchTab extends Component {
    render() {
        return (
            <Context.Consumer>
                {context => {
                    return (
                        <Container>
                            <TabContent activeTab={context.activeTab}>
                                <TabPane tabId="1">
                                    <Home />
                                </TabPane>
                                <TabPane tabId="2">
                                    <Popular />
                                </TabPane>
                                <TabPane tabId="3">
                                    <All />
                                </TabPane>
                            </TabContent>   
                        </Container>
                    )
                }}
            </Context.Consumer>
        )
    }
}

我要实现的功能是:

  • 只要URL为'/',就重定向到'/ home/'。
  • 只要URL为'/ home /',请从 activeTab并重新渲染Context,以便获得SwitchTab标签 打开。

当前的工作状态是每当我单击选项卡时,内容都会更改,但URL仍为home。如果将URL更改为/home//popular/,则不会更改内容。

1 个答案:

答案 0 :(得分:1)

该错误清楚地说明了问题所在,您需要将路径包装在div中,因为Router仅接受一个子元素。

此外,为了在Provider中设置状态,您需要使用setState或提供处理程序

class Provider extends Component {
  state = {

    loggedIn: false,
    username: '',
    password: '',
    loginModalOpen: false,
    signupModalOpen: false,
    navbarOpen: false,
    activeTab: '3',

    setActiveTab: (tab) => {
       this.setState({activeTab: tab});
    }

    toggleLoggedIn: () => {
      this.setState({loggedIn: !this.state.loggedIn});
    },

    toggleLoginModal: () => {
      this.setState({loginModalOpen: !this.state.loginModalOpen});
    },

    toggleSignupModal: () => {
      this.setState({signupModalOpen: !this.state.signupModalOpen});
    },


    toggleNavbar: () => {
      this.setState({navbarOpen: !this.state.navbarOpen})
    },

    toggleTab: (tab) => {
      if(this.state.activeTab !== tab) {
        this.setState({activeTab: tab});
      }
    }
  }

  render() {
    return (
        <Context.Provider value={this.state}>
            {this.props.children}
        </Context.Provider>
    )
  }
}

此外,由于您无法直接在渲染中设置状态,因此您需要创建一个处理这种情况的组件

class Handler extends React.Component {
   componentDidMount() {
      this.props.setActiveTab(this.props.activeTab);
   }
   render() {
     return null;
   }
}

您的路由器配置看起来像

<BrowserRouter>
   <div>
      <Route exact path='/' render={() => <Redirect to='/home/' /> } />
      <Route exact path='/home/' render={() => <Handler setActiveTab={setActiveTab} activeTab={'1'} />}/>
      <Route exact path='/popular/' render={() => <Handler setActiveTab={setActiveTab} activeTab={'2'} />}/>
      <Route exact path='/all/' render={() => <Handler setActiveTab={setActiveTab} activeTab={'3'} />}/>
   </div>
</BrowserRouter>