我是react
和redux
的新手,并一直在探索它与angular
的不同之处。
我正在尝试做一个简单的登录页面而无法达到我想要的效果。从登录表单中获取用户名和密码后,我将其提交如下:
submitHandler(e){
e.preventDefault();
var user = {
name : this.state.username,
password: this.state.password
}
this.props.authenticateUser(user);
browserHistory.push('/home');
this.setState({
username:'',
password:''
})
}
这里,authenticateUser
是我的reducer中的一个函数(如下所示),它从现有用户的列表中检查,然后检查具有属性isAuthenticated
的状态:
case 'AUTHENTICATE_USER':
var users = state.userslist;
var payloadUser = action.payload;
for (let i = 0; i < users.length; i++) {
let user = users[i]
if (user.name === payloadUser.name) {
return {...state, isAuthenticated: true };
}
};
return {...state, isAuthenticated: false };
现在在Angular中,我只是等待此调用完成并检查此值是true
还是false
,然后使用angular-router
导航到主页。
但是我如何在react
中实现同样的目标。我在我的示例应用程序中使用react-router
。
我尝试在isAuthenticated
下面的submitHandler
功能中检查this.props.authenticateUser(user)
this.props.isAuthenticateUser
,但问题是,false
未更新并返回initialState
},我在reducer中设置为isAuthenticated
。
请告诉我如何在authenticateUser
功能调用后检查promise
,以便我可以继续进行主页路由。我是否必须使用redux
并等待状态由isAuthenticated
更新,然后再次检查? (我知道反应是一种单向路径,它不会那样工作。)
此外,如果我的身份验证失败,如何在登录表单下方显示错误面板。我认为在错误面板中使用一个组件,它接受'rest_framework/api.html'
作为输入,并检查是否为false以显示(即。在Angular中的ngShow。)但我担心会不能正常工作,因为我的州不会及时更新。
我知道渲染函数将在状态发生任何变化时被调用。但我无法清楚地把我的脑袋包裹起来。
编辑:为简洁起见,我没有提供上面的操作创建者和完整缩减器,而是仅显示了身份验证用户的开关案例操作。我的应用程序遵循原始的redux架构,包括动作,减速器,容器,组件等。
编辑: Github链接here
答案 0 :(得分:11)
我将尝试简要解释数据流在Redux应用程序中的工作原理:
不应直接从组件调用reducer。您对身份验证用户的调用应该在操作中,这应该是从组件调度的内容。
定义操作时,可以指定属性以定义操作类型。例如,在这种情况下,它可以是type: AUTHENTICATE_USER
完成操作后,redux存储会使用当前状态和操作调用reducer。在这里,redux状态可以根据action.type
(上面的第二个代码片段)进行更新
这是最重要的部分:您的组件需要有mapStateToProps
方法,该方法将Redux状态中的值作为道具传递到组件中。因此,当状态发生变化时,道具会更新,组件会重新渲染。要使用mapStateToProps
,您需要实现react-redux库的连接。 (https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options)
为了实现你想要的,这就是我的建议:
在您的组件的componentWillReceiveProps
方法中,检查props.isAuthenticated
并使用context.router.push()
导航用户是否经过身份验证。
同时根据组件props.isAuthenticated
方法中的render
进行检查,以显示错误消息。
一些可能有用的链接:
答案 1 :(得分:2)
我更喜欢这样的代码:
const mapStateToProps = (state) => {
return {
isAuthenticated: state.isAuthenticated
}
}
class Dashboard extends PureComponent {
render() {
const { isAuthenticated } = this.props
return (
<div>
{ isAuthenticated ? (
<div>
<p>Hello</p>
</div>
) : (
Login()
)}
</div>
)
}
}
来源:https://stackoverflow.com/a/56899814/3850405
除了@Nupur的答案。 componentWillReceiveProps()
被认为是不安全的,方法名称现在为:UNSAFE_componentWillReceiveProps()
https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops
如果您想使用此方法,请改用componentDidUpdate()
,初始渲染不调用此方法。
componentDidUpdate(prevProps) {
if (this.props.isAuthenticated ) {
//perform code here
}
}
https://reactjs.org/docs/react-component.html#componentdidupdate