在嵌套的 React 组件中路由

时间:2021-01-19 10:20:16

标签: reactjs typescript react-redux react-router react-router-dom

我请你不要扔石头,因为每个人都曾经学习过)底线是这样的:我正在为自己和我的朋友们写一个愿望清单,我卡在了一个看似非常愚蠢的时刻。嵌套组件是一个带有导航选项卡和退出按钮的标题。因此,当我正在实施应用程序框架时,仅通过loggedInUser /!loggedInUser 进行授权。实际上,当你点击退出按钮时,一个空字符串被发送到loggedInUser 和history.push ('/login') 中。在调试器中,我看到正在发生调度并将位置推送到历史记录中,但由于某种原因,渲染条件将无法满足。我请求知识渊博的人的帮助。我想我在某处搞砸了路由,因为我读到由于某种原因没有使用 BrowserRouter,但没有它什么都不起作用。总的来说,提前致谢!

条目:

const history = createBrowserHistory()

ReactDOM.render(
  <Router history={history}>
    <Provider store={store}>
      <App />
    </Provider>
  </Router>,
  document.getElementById('root')
);

路由组件:

interface AppProps {
    loggedInUser: string;
}

class App extends React.Component<AppProps & RouteComponentProps> {
    state = { 
        loggedInUser: ""
    }

    render() {
        const history = this.props
        return (
            <>
                <BrowserRouter>
                    <Segment>
                        <Switch>
                            <Route history={history} path='/login' render={() => (!this.props.loggedInUser ? <LoginPage /> : <Redirect to="/account" />)}/>
                            <Route history={history} path='/account' render={() => (this.props.loggedInUser ? <AccountPage/> : <Redirect to="/login" />)}/>
                            <Route history={history} path='/friendslist' render={() => (this.props.loggedInUser ? <FriendsList/> : <Redirect to="/login" />)}/>
                            <Redirect from='/' to='/login' />
                        </Switch>
                    </Segment>
                </BrowserRouter>
            </>
        )
    }
}


const mapStateToProps = (state: StateInterface): AppProps => ({
    loggedInUser: state.loggedInUser
})

export default connect(mapStateToProps)(withRouter(App))

嵌套组件(它在每个路由组件中呈现):

interface HeaderProps extends HeaderPropsFromState{
    activeItem: string;
}

interface HeaderPropsFromState{
    loggedInUser: string;
}


class Header extends React.Component<HeaderProps & RouteComponentProps> {
    state = { 
        activeItem: this.props.activeItem,
    }

    handleItemClick = (e: any, { name }: any) => this.setState({ activeItem: name })

    render() {
        const { activeItem } = this.state
        const { match, history } = this.props
                return (
            <Menu pointing>
                        <Menu.Item
                            name='Friends'
                            active={activeItem === 'Friends'}
                            onClick={this.handleItemClick}
                            as={Link}
                            to="/friendslist"
                        />
                        <Menu.Item
                            name='Account'
                            active={activeItem === 'Account'}
                            onClick={this.handleItemClick}
                            as={Link}
                            to="/account"
                        />
                        {activeItem === 'Friends' &&
                            <Menu.Menu position='right'>
                                <Menu.Item>
                                    <Input icon='users' iconPosition='left' placeholder='Search users...' />
                                    {/* TODO: create function to filter by friend's name */}
                                </Menu.Item>
                            </Menu.Menu>
                        }
                        {activeItem === 'Account' &&
                            <Menu.Menu position='right'>
                                <Menu.Item>
                                    <Button basic 
                                    color='black'
                                    onClick={() => {
                                        console.log(this.props.loggedInUser)
                                        store.dispatch(setLoggedInUser({username: ""}))
                                        history.push('/login')
                                    }}
                                    >Exit</Button>
                                    {/* TODO: create function to exit from account */}
                                </Menu.Item>
                            </Menu.Menu>
                        }
                    </Menu>
        )
    }
}


const mapStateToProps = (state: StateInterface): HeaderPropsFromState => ({
    loggedInUser: state.loggedInUser
})

export default connect(mapStateToProps)(withRouter(Header))

Image just for better understanding

UPD:包含头组件的组件。

class FriendsList extends React.Component{
    users = [...users objects]

    render() {
        const usersList = this.users.map((user: User, index: number) =>
                <OneFriendWishes user={user} key={index}/>
            )
        return (
            <>
                <Header activeItem={"Friends"}/>
                {usersList}
            </>
        )
    }
}

export default FriendsList

0 个答案:

没有答案