【发布时间】:2018-09-21 11:54:32
【问题描述】:
我正在尝试按照example 在 React Router v4 中创建经过身份验证的路由。显示后代的代码:
function PrivateRoute ({component: Component, authed, ...rest}) {
return (
<Route
{...rest}
render={(props) => (!!authed)
? <Component {...props} />
: <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
/>
)
}
我的身份验证状态 (authed) 在 reducer 中初始化为空对象,它是从 Redux 存储中派生的。这就是我的 App.js 的样子:
class App extends Component {
componentDidMount() {
const token = localStorage.getItem("token");
if (token) {
this.props.fetchUser();
}
}
render() {
return (
<Router>
<div>
<PrivateRoute authed={this.props.authed} path='/dashboard' component={Dashboard} />
/>
</div>
</Router>
);
}
}
问题在于authed 状态以未定义的形式开始,然后,一旦安装了路由器组件,它就会将状态更新为true。然而这有点晚了,因为用户已经被重定向回登录页面。我还尝试用componentWillMount() 替换componentDidMount() 生命周期方法,但这也没有解决问题。
你会建议什么策略?
更新 1:我解决此问题的唯一方法是在返回 <Route /> 组件之前测试 authed 状态,例如:
render() {
if (!!this.props.authed) {
return (
<Router>
<div>
...
更新 2:我正在使用 Redux Thunk 中间件来调度操作。状态作为道具正确传递 - 我在 PrivateRoute 组件中使用 console.log() 方法来验证状态是否正确变化。问题当然是变异晚了,Route 已经在重定向用户了。
reducer 和 action 的粘贴代码...
行动:
export const fetchUser = () => async dispatch => {
dispatch({ type: FETCHING_USER });
try {
const res = await axios.get(`${API_URL}/api/current_user`, {
headers: { authorization: localStorage.getItem("token") }
});
dispatch({ type: FETCH_USER, payload: res.data });
} catch (err) {
// dispatch error action types
}
};
减速机:
const initialState = {
authed: {},
isFetching: false
};
...
case FETCH_USER: // user authenticated
return { ...state, isFetching: false, authed: action.payload };
【问题讨论】:
-
你是如何获得 'authed' 的值的,你有没有试过调查为什么 authed 调用需要很长时间,你能分享那个代码。
-
@alowsarwar 这是对 nodejs 服务器的 Axios 调用,返回 Passport 用户对象(从 jwt 令牌反序列化)
-
@James 您能告诉我有关 UPDATE 1 解决方案的信息吗,您在哪里查看
(!!this.props.authed)?我也有同样的问题。 -
@Arnab 在渲染
<Route />组件之前,我正在测试 authed 状态是否存在。换句话说,为了回答你的问题,我正在我的路线文件中检查它。 -
@James 好的,谢谢。我将尝试您的解决方案,同时尝试用不同的方法解决它。这不是最优选的方法。但现在问题没有发生。你可以查看我的答案,我已经在下面发布了。
标签: reactjs react-redux react-router-v4