我有一个像这样定义的组件。 fetchBrands
是一项redux行动。
class Brands extends Component {
componentWillMount() {
this.props.fetchBrands();
}
render() {
return (
// jsx omitted for brevity
);
}
}
function mapStateToProps(state) {
return { brands: state.brands.brands }
}
export default connect(mapStateToProps, { fetchBrands: fetchBrands })(Brands);
此组件包含在高阶组件中,如下所示:
export default function(ComposedComponent) {
class Authentication extends Component {
// kind if like dependency injection
static contextTypes = {
router: React.PropTypes.object
}
componentWillMount() {
if (!this.props.authenticated) {
this.context.router.push('/');
}
}
componentWillUpdate(nextProps) {
if (!nextProps.authenticated) {
this.context.router.push('/');
}
}
render() {
return <ComposedComponent {...this.props} />
}
}
function mapStateToProps(state) {
return { authenticated: state.auth.authenticated };
}
return connect(mapStateToProps)(Authentication);
}
然后,在我的路由器配置中,我正在执行以下操作:
<Route path="brands" component={requireAuth(Brands)} />
如果身份验证令牌不存在于本地存储中,我会重定向到公共页面。但是,仍在调用fetchBrands
操作,该操作将触发ajax请求。由于缺少身份验证令牌,服务器拒绝它,但我不希望甚至进行呼叫。
export function fetchBrands() {
return function(dispatch) {
// ajax request here
}
}
我可以使用if/else
检查来包装ajax请求,但考虑到我需要执行此操作的所有操作功能,这并非常干。如何实现DRY到如果auth在浏览器级别失败,则阻止调用?
答案 0 :(得分:0)
你应该为此编写一个中间件。 http://redux.js.org/docs/advanced/Middleware.html
由于您使用的是axios,我建议您使用https://github.com/svrcekmichal/redux-axios-middleware
之类的东西然后你可以使用像
这样的中间件const tokenMiddleware = store => next => action => {
if (action.payload && action.payload.request && action.payload.request.secure) {
const { auth: { isAuthenticated } } = store.getState()
const secure = action.payload.request.secure
if (!isAuthenticated && secure) {
history.push({ pathname: 'login', query: { next: history.getCurrentLocation().pathname } })
return Promise.reject(next({ type: 'LOGIN_ERROR', ...omit(action, 'payload') }))
}
}
return next(action)
}
action.payload.request.secure是我用来表示请求需要身份验证的自定义提示。
在这种情况下,我还使用react-routing中的历史重定向,但是你可以处理这个以分发另一个动作(store.dispatch({whatever}))并根据需要做出反应