React.js-在路由过程中道具没有改变

时间:2018-07-16 10:59:33

标签: javascript reactjs

我有一个BrowserRouter,它基于Route呈现不同的组件。其中大多数组件具有相似的标记

因此,我创建了一个Wrapper组件,它将接收道具,并提供其{children}(如果提供)。此WrapperRoute中被调用。

import React, {Component} from 'react'
import Context from '../../provider'
import { 
    BrowserRouter,
    Route,
    Redirect,
    Switch,
} from "react-router-dom"
import {
    Container,
    Row,
    Col,
} from 'reactstrap'
import Profile from './ContentComponent/Profile'
import Subreddit from './ContentComponent/Subreddit'
import PostExpanded from './ContentComponent/PostExpanded'
import InfoComponent  from './InfoComponent'
import SwitchTab from './ContentComponent/Subreddit/SwitchTab'
import NewPost from './ContentComponent/assets/NewPost'
import './style.css'

class Wrapper extends React.Component {
    componentDidMount() {
        this.props.setActiveTab(this.props.activeTab);
    }

    render() {
        {console.log('Wrapper props: ', this.props)}
        return (
            <Row>
                <Col md='8' id='content-block'>
                    <SwitchTab />
                    {this.props.children}
                </Col>
                <Col md='4' id='info-block'>
                    <InfoComponent info={this.props.info} {...this.props}/>
                </Col>
            </Row>
        )
    }
}

export default class BodyComponent extends Component {
    render() {
        return (
            <BrowserRouter>
                <Context.Consumer>
                    {context => {
                        return (
                            <Container>
                                <Switch>
                                    <Route 
                                        exact 
                                        path='/' 
                                        render={() =>
                                            <Redirect to='r/home/' />
                                        }
                                    />
                                    <Route 
                                        exact 
                                        path='/r/home/' 
                                        render={() => 
                                            <Wrapper 
                                                setActiveTab={context.toggleTab}
                                                activeTab={'1'} 
                                                info='home'
                                            />
                                        }
                                    />
                                    <Route 
                                        exact 
                                        path='/r/popular/' 
                                        render={() => 
                                            <Wrapper 
                                                setActiveTab={context.toggleTab} 
                                                activeTab={'2'} 
                                                info='popular'
                                            />
                                        }
                                    />
                                    <Route 
                                        exact 
                                        path='/r/all/' 
                                        render={() =>
                                            <Wrapper 
                                                setActiveTab={context.toggleTab} 
                                                activeTab={'3'} 
                                                info='all'
                                            />
                                        }
                                    />
                                    <Route 
                                        exact 
                                        path='/u/:username/' 
                                        render={(props) => {
                                            return (
                                                <Wrapper 
                                                    setActiveTab={context.toggleTab} 
                                                    activeTab={'4'}
                                                    info='user'
                                                    user={props.match.params.username}
                                                >
                                                    <Profile username={props.match.params.username} />
                                                </Wrapper>
                                            )
                                        }}
                                    />
                                    <Route
                                        exact
                                        path = '/r/:subreddit/new/'
                                        render={(props) => {
                                            return (
                                                <Wrapper 
                                                    setActiveTab={context.toggleTab} 
                                                    activeTab={'4'} 
                                                    info='subreddit'
                                                    subreddit={props.match.params.subreddit}
                                                >
                                                    <NewPost />
                                                </Wrapper>
                                            )
                                        }}
                                    />
                                    <Route
                                        exact
                                        path = '/r/:subreddit/post/:postid/'
                                        render={(props) => {
                                            return (
                                                <Wrapper 
                                                    setActiveTab={context.toggleTab} 
                                                    activeTab={'4'} 
                                                    info='subreddit'
                                                    subreddit={props.match.params.subreddit}
                                                >
                                                    <PostExpanded
                                                        subreddit={props.match.params.subreddit}
                                                        postid={props.match.params.postid}
                                                    />
                                                </Wrapper>
                                            )
                                        }}
                                    />
                                    <Route
                                        exact
                                        path='/r/:subreddit/'
                                        render={(props) => {
                                            return (
                                                <Wrapper 
                                                    setActiveTab={context.toggleTab} 
                                                    activeTab={'4'} 
                                                    info='subreddit'
                                                    subreddit={props.match.params.subreddit}
                                                >
                                                    <Subreddit subreddit={props.match.params.subreddit} />
                                                </Wrapper>
                                            )
                                        }}
                                    />
                                    <Route
                                        exact
                                        path = '/new/'
                                        render={(props) => {
                                            return (
                                                <Wrapper
                                                    setActiveTab={context.toggleTab}
                                                    activeTab={'4'}
                                                    info='new'
                                                >
                                                    <NewPost />
                                                </Wrapper>
                                            )
                                        }}
                                    />
                                </Switch>
                            </Container>
                        )
                    }}
                </Context.Consumer>
            </BrowserRouter>
        )
    }
}

我在这里面临多个问题,我想可以一次解决所有问题,我不知道怎么办?

  1. 当我更改 URL 时,包装道具没有发生变化 使用props.history.push

    <NavItem>
        <NavLink
            className={classnames({ active: context.activeTab === '1' })}
            onClick={() =>{
                context.toggleTab('1');
                this.props.history.push('/r/home/')
            }}
        >
        Home
        </NavLink>
    </NavItem>
    <NavItem>
        <NavLink
            className={classnames({ active: context.activeTab === '2' })}
            onClick={() => {
                context.toggleTab('2');
                this.props.history.push('/r/popular/')
            }}
        >
        Popular
        </NavLink>
    </NavItem>
    

1 个答案:

答案 0 :(得分:0)

我认为在遍历代码时遇到了问题。因此,当我想在props.history.push中使用HeaderComponent时,问题就开始了。我遇到了错误,因此我将其用BrowserRouter包装并导出了withRouter(),这使我可以使用props.history.push

因此,在不知不觉中我创建了2个BrowserRouter

<React.Fragment>
    <BrowserRouter>
        <NavbarComponent />
        <TabComponent />
    </BrowserRouter>
    <BrowserRouter>
        <Switch>
            <Route ... />
            <Route ... />
        </Switch>
    </BroserRouter>
</React.Fragment>

因此,我正在TabComponent中更改 URL ,并希望能更改我的Route并修改内容。

拥有一个全局BrowserRouter(不要认为 global的是正确的词,但是)解决了这个问题。

<React.Fragment>
    <BrowserRouter>
        <NavbarComponent />
        <TabComponent />
        <Switch>
            <Route ... />
            <Route ... />
        </Switch>
    </BroserRouter>
</React.Fragment>