Javascript 如何将身份验证状态传递给嵌套组件
我是react和redux新手,我正在尝试创建一个私有嵌套路由。登录时,我被重定向到/userdashboard,令牌也从服务器返回并存储到本地存储。 每当用户中的Im被加载时,帖子就会被加载。 但是当我刷新时,AUTH_ERROR操作被调度,令牌从本地存储中删除,我被重定向 我尝试调用相同的操作来加载嵌套组件上的用户,但仍然调度了AUTH_ERROR操作 我的App.jsJavascript 如何将身份验证状态传递给嵌套组件,javascript,reactjs,redux,react-redux,react-router,Javascript,Reactjs,Redux,React Redux,React Router,我是react和redux新手,我正在尝试创建一个私有嵌套路由。登录时,我被重定向到/userdashboard,令牌也从服务器返回并存储到本地存储。 每当用户中的Im被加载时,帖子就会被加载。 但是当我刷新时,AUTH_ERROR操作被调度,令牌从本地存储中删除,我被重定向 我尝试调用相同的操作来加载嵌套组件上的用户,但仍然调度了AUTH_ERROR操作 我的App.js import React, { Fragment, useEffect } from 'react'; import {
import React, { Fragment, useEffect } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Landing from './components/layout/Landing/Landing';
import Register from './components/auth/Register';
import Login from './components/auth/Login';
import Alert from './components/layout/Alert/Alert';
import UserDasboard from './components/userdashboard/UserDashboard';
import PrivateRoute from './components/routing/PrivateRoute';
//Redux
import { Provider } from 'react-redux';
import store from './store';
import { loadUser } from './actions/auth';
import setAuthToken from './utils/setAuthToken';
import './App.scss';
if (localStorage.token) {
setAuthToken(localStorage.token);
}
const App = () => {
useEffect(() => {
store.dispatch(loadUser());
}, []);
return (
<Provider store={store}>
<Router>
<Fragment>
<Alert />
<Switch>
<PrivateRoute path='/userdashboard' component={UserDasboard} />
<Route exact path='/register' component={Register} />
<Route exact path='/login' component={Login} />
<Route exact path='/' component={Landing} />
</Switch>
</Fragment>
</Router>
</Provider>
);
};
export default App;
//setAuthToken
import axios from 'axios';
const setAuthToken = token => {
if (token) {
axios.defaults.headers.common['x-auth-token'] = token;
} else {
delete axios.defaults.headers.common['x-auth-token'];
}
};
export default setAuthToken;
你能为loadUser和setAuthToken添加源吗?@SuleymanSah我刚刚更新了答案上的代码。你可以检查loadUser和setAuthToken。你从哪里获得令牌并保存在localStorage中?我认为在loadUser操作中,在成功登录之后,应该从响应主体或响应头获取令牌,并将其保存在localStorage中。我正在添加示例代码作为答案。
import React, { Fragment, useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import PostItem from './PostItem';
import { getPosts } from '../../actions/post';
const Posts = ({ getPosts, post: { posts, loading } }) => {
useEffect(() => {
getPosts();
}, [getPosts]);
return loading ? (
<p>Loading</p>
) : (
<Fragment>
<section className='section'>
<div className='columns'>
{/* Post form*/}
<div className='columns'>
{posts.map(post => (
<PostItem
key={post._id}
post={post}
subs={post.subscribedusers}
/>
))}
</div>
</div>
</section>
</Fragment>
);
};
Posts.propTypes = {
getPosts: PropTypes.func.isRequired,
post: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
post: state.post
});
export default connect(
mapStateToProps,
{ getPosts }
)(Posts);
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import Moment from 'react-moment';
import { connect } from 'react-redux';
import { addSubscriber, removeSubscriber } from '../../actions/post';
const PostItem = ({
addSubscriber,
removeSubscriber,
auth,
post: {
_id,
posttitle,
posttext,
postimage,
user,
subscribedusers,
userposts,
date
},
subs
}) => {
const sub = subs.map(sub => sub);
return (
<div className='column'>
<Link to={`/post/${_id}`}>
<div class='card'>
<div class='card-image'>
<figure class='image is-4by3'>
<img src={postimage} alt='Placeholder image' />
</figure>
</div>
<div class='card-content'>
<div class='media'>
<div class='media-left'>
<figure class='image is-48x48'>
<img
src='#'
alt='Placeholder image'
/>
</figure>
</div>
<div class='media-content'>
<p class='title is-4'>{posttitle}</p>
{/* <p class='subtitle is-6'>@johnsmith</p> */}
</div>
</div>
<div class='content'>
<p>{posttext}</p>
<br />
<time datetime='2016-1-1'>
<Moment format='YYYY/MM/DD'>{date}</Moment>
</time>
</div>
<footer class='card-footer'>
<p class='card-footer-item'>
Subscriptions{' '}
{subscribedusers.length > 0 && (
<span>{subscribedusers.length}</span>
)}
</p>
<p class='card-footer-item'>{userposts.length}</p>
<button className='button' onClick={e => addSubscriber(_id)}>
Subscribe
</button>
<button className='button' onClick={e => removeSubscriber(_id)}>
UnSubscribe
</button>
</footer>
</div>
</div>
</Link>
</div>
);
};
PostItem.propTypes = {
post: PropTypes.object.isRequired,
auth: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth
});
export default connect(
mapStateToProps,
{ addSubscriber, removeSubscriber }
)(PostItem);
export const loadUser = () => async dispatch => {
if (localStorage.token) {
setAuthToken(localStorage.token);
}
try {
const res = await axios.get('userapi/auth');
dispatch({
type: USER_LOADED,
payload: res.data
});
} catch (err) {
dispatch({
type: AUTH_ERROR
});
}
};
import axios from 'axios';
const setAuthToken = token => {
if (token) {
axios.defaults.headers.common['x-auth-token'] = token;
} else {
delete axios.defaults.headers.common['x-auth-token'];
}
};
export default setAuthToken;