Javascript 如何将身份验证状态传递给嵌套组件

Javascript 如何将身份验证状态传递给嵌套组件,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 {

我是react和redux新手,我正在尝试创建一个私有嵌套路由。登录时,我被重定向到/userdashboard,令牌也从服务器返回并存储到本地存储。 每当用户中的Im被加载时,帖子就会被加载。 但是当我刷新时,AUTH_ERROR操作被调度,令牌从本地存储中删除,我被重定向

我尝试调用相同的操作来加载嵌套组件上的用户,但仍然调度了AUTH_ERROR操作

我的App.js

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;