Я хочу отобразить имя пользователя и изменить текст кнопки на «выход» с «вход» в Navbar (компонент навигации), когда пользователь вошел в систему. Я устал повторно отображать компонент навигации, переместив местоположение истории маршрутизатора на домашнюю страницу для пользователя, вошедшего в систему. в.
this.props.history.push('/')
Затем пользователь может успешно войти в систему, данные пользователя сохраняются в локальном хранилище, а местоположение маршрутизатора изменяется. данные сохраняются в localStorage, но компонент не перерисовывается.
Вот что я пробовал.
попытался понизить версию «connected-react-router» до «v6.0.0», но это выдало мне несколько ошибок. поэтому верните последнюю версию «^ 6.4.0».
попытался добавить код Navbar в App.js, который является родительским компонентом. Но сам app.js не перерисовывается ни для пользователя, вошедшего в систему.
import React from 'react';
import { connect } from 'react-redux';
/* --- Components --- */
import Nav from './src/components/nav';
import Loader from './src/shared/loader';
import './styles/main.scss';
const FlashMessagesContainer = Loader({
loader: () =>
import('./src/shared/flassMessagesContainer' /* webpackChunkName: 'FlashMessagesContainer' */),
});
const App = (props, { isOnModal }) => (
<div id = "app">
<Nav />
{!isOnModal && (
<div className = "flex justify-center">
<FlashMessagesContainer />
</div>
)}
{props.children}
</div>
);
const mapPropsToState = state => ({
isOnModal: state.modal.show,
});
export default connect(
mapPropsToState,
null,
)(App);
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link, withRouter } from 'react-router-dom';
/* --- Components --- */
import {
isLoggedIn,
getCompanyName,
clearLocalStorage,
} from '../../localStorage';
class Nav extends Component {
handleUserLogout = async ev => {
ev.preventDefault();
await clearLocalStorage();
return this.props.history.push('/login');
};
render() {
return (
<div className = "nav">
{isLoggedIn() ? (
<div className = "flex">
<p className = "mr3 mt2">
안녕하세요. <span className = "b">{getCompanyName()}</span>
 님,
</p>
<button
type = "button"
className = "login-btn td-none c-text br f-mini"
onClick = {this.handleUserLogout}
>
로그아웃
</button>
</div>
) : (
<Link className = "login-btn td-none c-text br f-mini" to = "/login">
로그인
</Link>
)}
</div>
);
}
}
export default withRouter(Nav);
export const getToken = () => localStorage.token;
export const getCompanyName = () => localStorage.companyName;
export const isLoggedIn = () => !!localStorage.token;
export const saveUserNameAndToken = userData => {
localStorage.setItem('token', userData.token);
localStorage.setItem('companyName', userData.companyName);
};
export const clearLocalStorage = () => localStorage.clear();
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter as Router } from 'connected-react-router';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import configureStore, { history } from './store';
import Routes from './routes';
const theme = createMuiTheme({
...
});
const store = configureStore();
const root = document.createElement('div');
document.body.appendChild(root);
render(
<Provider store = {store}>
<MuiThemeProvider theme = {theme}>
<Router history = {history}>
<Routes />
</Router>
</MuiThemeProvider>
</Provider>,
root,
);
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import { hot, setConfig } from 'react-hot-loader';
import { withRouter } from 'react-router';
/* --- Components --- */
import App from './app';
import Loader from './src/shared/loader';
const Home = Loader({
loader: () =>
import('./src/components/home/homeContainer' /* webpackChunkName: 'Home' */),
});
...
const routes = props => (
<div>
<App history = {props.history} />
<Switch>
<Route exact path = "/" component = {Home} />
<Route path = "/login" render = {props => <Login {...props} />} />
<Route path = "/users/account" component = {Users} />
<Route component = {NoMatch} />
</Switch>
</div>
);
const Routes =
!module.hot || process.env.NODE_ENV === 'production'
? routes
: hot(module)(routes);
export default withRouter(Routes);
Я ожидаю, что компонент Nav будет перерисован при изменении местоположения маршрутизатора.
react: ^16.8.6
react-dom: ^16.8.6
react-loadable: ^5.5.0
react-redux: ^6.0.0
react-router-dom: ^4.3.1
redux: ^4.0.0
connected-react-router: ^6.4.0
Сохраняетесь ли вы isLoggedIn
в своем состоянии редукции?
Спасибо ! Проблема устранена :)
Я исправил это, сохранив состояние isLoggedIn в хранилище избыточности. И чтобы сохранить состояние из хранилища избыточности при обновлении страницы, я использовал 'redux-persist'.
Теперь компонент Nav перерисовывается при изменении местоположения маршрутизатора, а данные userName сохраняются даже при обновлении страницы.
const initialState = {
isLoggedIn: false,
userName: '',
};
const auth = (state = initialState, action) => {
switch (action.type) {
case types.USER_LOGIN:
return {
...state,
isLoggedIn: true,
userName: action.payload,
};
case types.USER_LOGOUT:
return {
...state,
isLoggedIn: false,
userName: '',
};
default:
return state;
}
};
...
{this.props.isLoggedIn ? (
...
) : (
...
)}
...
const mapStateToProps = state => ({
isLoggedIn: state.auth.isLoggedIn,
userName: state.auth.userName,
});
const mapDispatchToProps = dispatch => ({
userLogout: () => dispatch(userLogout()),
});
export default withRouter(
connect(
mapStateToProps,
mapDispatchToProps,
)(Nav),
);
import { applyMiddleware, createStore } from 'redux';
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger';
import { composeWithDevTools } from 'redux-devtools-extension';
import { routerMiddleware } from 'connected-react-router';
import createBrowserHistory from 'history/createBrowserHistory';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import createRootReducer from './src/reducers';
export const history = createBrowserHistory();
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(
persistConfig,
createRootReducer(history),
);
const store = createStore(
persistedReducer,
composeWithDevTools(
applyMiddleware(
routerMiddleware(history),
thunkMiddleware,
createLogger({
predicate: () => process.env.NODE_ENV === 'development',
collapsed: true,
}),
),
),
);
export const persistor = persistStore(store);
export default store;
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter as Router } from 'connected-react-router';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { PersistGate } from 'redux-persist/lib/integration/react';
import store, { history, persistor } from './store';
import Routes from './routes';
import Loading from './src/shared/loading';
const theme = createMuiTheme({
palette: {
primary: { main: '#AE9A65' },
secondary: { main: '#ee9105' },
success: { main: '#43A047' },
warning: { main: '#FFA000' },
error: { main: '#ed4337' },
info: { main: '#2196F3' },
},
});
const root = document.createElement('div');
document.body.appendChild(root);
render(
<Provider store = {store}>
<PersistGate loading = {<Loading />} persistor = {persistor}>
<MuiThemeProvider theme = {theme}>
<Router history = {history}>
<Routes />
</Router>
</MuiThemeProvider>
</PersistGate>
</Provider>,
root,
);
현재 <Nav /> 에서는 LocalStorage에서 값을 직접 불러오고 있기때문에, history 이동이 되었더라도, <Nav />갵 리렌덀맀맔맊.