如何等待一个动作完成?
Posted
技术标签:
【中文标题】如何等待一个动作完成?【英文标题】:How to wait for an action to complete? 【发布时间】:2017-06-22 15:41:41 【问题描述】:我是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
。
我试图在我调用this.props.authenticateUser(user)
的submitHandler
函数下方检查isAuthenticated
,但问题是,this.props.isAuthenticateUser
未更新并返回false
,我已将其设置为@987654340 @ 在我的减速器中。
请告诉我在调用authenticateUser
函数后如何检查isAuthenticated
,以便我可以继续我的主页路由。我是否必须使用promise
并等待redux
更新状态然后再次检查? (我知道 react 是一种单向路径,但它不会那样工作。)
此外,如果我的身份验证失败,如何在我的登录表单下方显示一个错误面板。我认为为错误面板使用一个组件,该组件以isAuthenticated
作为输入并检查是否为 false 以显示 (即 ngShow 就像在 Angular 中一样。) 但恐怕这行不通同样,因为我的状态不会及时更新。
我知道渲染函数会在状态发生任何变化时被调用。但我就是无法清楚地了解 React。
编辑:为简洁起见,我没有提供上面的动作创建者和完整的减速器,而只显示了身份验证用户的 switch case 操作。我的应用程序遵循原始的 redux 架构,包括操作、reducers、容器、组件等。
编辑: Github 链接here
【问题讨论】:
github.com/V1cHu/react-redux 这个网址转到 404 页面。你能分享正确的网址吗 【参考方案1】:我更喜欢这样的代码:
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://***.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
【讨论】:
【参考方案2】:我将尝试简要解释数据流在 Redux 应用程序中的工作原理:
不应直接从组件调用 reducer。您对身份验证用户的调用应该在一个操作中,并且应该从组件中分派。
定义动作时,可以给一个属性来定义动作的类型。例如,在这种情况下,它可能是type: AUTHENTICATE_USER
action 完成后,redux store 用当前 state 和 action 调用 reducer where。这里可以根据action.type
更新redux状态(上面第二个代码sn-p)
这是最重要的部分:您的组件需要有一个 mapStateToProps
方法,该方法将 Redux 状态中的值作为 props 传递到您的组件中。因此,随着状态的变化,道具会更新并且组件会重新渲染。要使用mapStateToProps
,您需要从 react-redux 库中实现连接。 (https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options)
为了实现你想要的,这是我的建议:
在组件的componentWillReceiveProps
方法中,检查props.isAuthenticated
并使用context.router.push()
导航用户是否已通过身份验证。
还在组件的render
方法中基于props.isAuthenticated
进行检查以显示错误消息。
一些可能有用的链接:
https://redux.js.org/basics/data-flow
https://redux.js.org/basics/usage-with-react
【讨论】:
我确实有 mapStateToProps ,这是我注入 isAuthenticated 的地方,但问题是我不知道何时以及如何在发送操作后检查。因为在调用 isAuthenticated 之后立即检查 isAuthenticated,所以我没有定义。状态不会立即更新。 在正确设置的 Redux 应用程序中,一旦您收到响应并调用 reducer,状态就会更新。通过查看您的代码,我可能会为您提供更多帮助。你可能在 Gihub 上有它吗? 我现在正在工作。将代码推送到 github 并在我回家后与您分享链接。 我已经用代码链接编辑了问题。请帮忙。 我只是看了你的代码,我仍然坚持我之前的两个建议。 login-form.js 组件中的componentWillReceiveProps
方法将跟踪对道具的更改,您可以基于props.isAuthenticated
进行重定向。更多信息在这里:facebook.github.io/react/docs/…以上是关于如何等待一个动作完成?的主要内容,如果未能解决你的问题,请参考以下文章