Роутинг во вложенном компоненте React
Попрошу камнями не кидаться, ибо все когда то учились) Суть такова: пишу вишлист для себя и друзей, и застрял на кажется очень глупом моменте. Вложенный компонент - это хедер с табами для навигации и кнопкой выхода. Пока реализую каркас приложения, по этому авторизация происходит просто по loggedInUser/!loggedInUser. Собственно при клике на exit button диспатчится пустая строка в 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))
Вложенный компонент(UPD: он рендерится в каждом из маршрутизируемых компонентов):
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))
Ответы (1 шт):
В общем то проблема была вовсе не в самом роутинге, а в условии редиректа.
Вместо:
<Route history={history} path='/login' render={() => (!this.props.loggedInUser ? <LoginPage /> : <Redirect to="/account" />
Теперь:
<Route history={history} path='/login' render={() => loggedInStatus ? <Redirect to="/account" /> :<LoginPage />}/>
Где this.props.loggedInUser - был строкой в которую диспатчился либо имя юзера в случае авторизации, либо !!ПУСТАЯ СТРОКА?!! в случае выхода из аккаунта. Решил же проблему просто добавлением поля с булевым значением в стейт и теперь loggedInStatus - либо true, либо false. В общем такая вот глупость, возможно кому то поможет...
