我有一个更新我的应用程序的通知状态的操作.通常,此通知将是某种错误或信息.我需要在5秒后发送另一个操作,将通知状态返回到初始状态,因此不会发出通知.这背后的主要原因是提供通知在5秒后自动消失的功能.
我没有运气使用setTimeout
和返回另一个动作,也无法找到如何在线完成.所以欢迎任何建议.
现在有很多关于redux镇最新孩子的讨论,redux-saga/redux-saga.它使用生成器函数来监听/调度操作.
在我绕过它之前,我想知道redux-saga
使用redux-thunk
async/await时使用的优点/缺点而不是下面的方法.
组件可能看起来像这样,像往常一样调度动作.
import { login } from 'redux/auth';
class LoginForm extends Component {
onClick(e) {
e.preventDefault();
const { user, pass } = this.refs;
this.props.dispatch(login(user.value, pass.value));
}
render() {
return (<div>
<input type="text" ref="user" />
<input type="password" ref="pass" />
<button onClick={::this.onClick}>Sign In</button>
</div>);
}
}
export default connect((state) => ({}))(LoginForm);
Run Code Online (Sandbox Code Playgroud)
然后我的行为看起来像这样:
// auth.js
import request from 'axios';
import { loadUserData } from './user';
// define constants
// define initial state
// export default reducer …
Run Code Online (Sandbox Code Playgroud) 我刚刚开始使用ReactJS,而且我对我遇到的问题有点困惑.
我的应用程序本质上是一个带有过滤器的列表和一个更改布局的按钮.目前我使用的三个组成部分:<list />
,< Filters />
和<TopBar />
,现在很明显,当我更改设置的< Filters />
我想在引发一些方法<list />
来更新我的看法.
如何让这3个组件相互交互,或者我是否需要某种全局数据模型,我可以在其中进行更改?
我一直在努力寻找解决这个问题的方法......
我正在开发一个带有在线记分牌的游戏.玩家可以随时登录和注销.完成游戏后,玩家将看到记分牌,并查看自己的排名,并自动提交分数.
记分牌显示了玩家的排名和排行榜.
当用户完成播放(提交分数)以及用户只想查看他们的排名时,使用记分板.
这是逻辑变得非常复杂的地方:
如果用户已登录,则将首先提交分数.保存新记录后,将加载记分板.
否则,将立即加载记分板.玩家将获得登录或注册的选项.之后,将提交分数,然后记分板将再次刷新.
但是,如果没有要提交的分数(只需查看高分表).在这种情况下,只需下载播放器的现有记录.但由于此操作不会影响记分牌,因此记分牌和玩家记录应同时下载.
有无限数量的级别.每个级别都有不同的记分牌.当用户查看记分板时,用户正在"观察"该记分板.当它关闭时,用户停止观察它.
用户可以随时登录和注销.如果用户注销,则用户的排名应该消失,如果用户以另一个帐户登录,则应该获取并显示该帐户的排名信息.
...但是,此信息只应针对用户当前正在观察的记分板进行.
对于查看操作,结果应缓存在内存中,以便如果用户重新订阅同一记分板,则不会提取.但是,如果提交了分数,则不应使用缓存.
任何这些网络操作都可能失败,并且播放器必须能够重试它们.
这些操作应该是原子的.所有状态都应该一次更新(没有中间状态).
目前,我能够使用Bacon.js(功能性反应式编程库)来解决这个问题,因为它提供了原子更新支持.代码非常简洁,但现在它是一个混乱的不可预测的意大利面条代码.
我开始看Redux.所以我尝试构建商店,并想出了类似的东西(用YAMLish语法):
user: (user information)
record:
level1:
status: (loading / completed / error)
data: (record data)
error: (error / null)
scoreboard:
level1:
status: (loading / completed / error)
data:
- (record data)
- (record data)
- (record data)
error: (error / null)
Run Code Online (Sandbox Code Playgroud)
问题变成:我在哪里放置副作用.
对于无副作用的动作,这变得非常容易.例如,在LOGOUT
行动时,record
减速器可以简单地将所有记录都抛出.
但是,某些行为确实有副作用.例如,如果我在提交分数之前没有登录,那么我成功登录,该SET_USER
操作将用户保存到商店中.
但是因为我有一个要提交的分数,这个SET_USER
动作也必须引发一个AJAX请求,同时设置record.levelN.status
为loading
.
问题是:当我以原子方式登录时,我如何表示应该发生副作用(得分提交)?
在Elm架构中,更新程序在使用形式时也会发出副作用 …
我读到Redux Thunk是管理异步操作/请求的可靠方法.没有太多关于通过其他行动调度行动的事情.
如何调度同步动作?我不确定thunk方法的性能问题,但是我可以在其他动作创建者中调度动作而不在其中定义函数吗?
在我看来,使用redux thunk对于这种需求是不必要的.
我不明白需要什么redux-thunk
.据我所知,a thunk
是一个返回函数的函数.在我看来,包装的表达式和中间件的使用可以做更多的工作来模糊正在发生的事情.取自redux-thunk
的示例代码
import thunk from 'redux-thunk';
// Note: this API requires redux@>=3.1.0
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
// Meet thunks.
// A thunk is a function t hat returns a function.
// This is a thunk.
function makeASandwichWithSecretSauce(forPerson) {
// Invert control!
// Return a function that accepts `dispatch` so we can dispatch later.
// Thunk middleware knows how to turn thunk async actions into actions.
return function (dispatch) {
return fetchSecretSauce().then(
sauce …
Run Code Online (Sandbox Code Playgroud) 为什么使用Redux Thunk然后可以做这样的事情:
ReadableAPI.getCategories().then((categories)=>{
console.log('after getCategories', categories)
this.props.dispatch(addCategories(categories))
})
Run Code Online (Sandbox Code Playgroud)
这不是更直接,并实现同样的事情?
我已经使用redux大约两个月了,并且刚刚开始探索处理异步行为的不同方法,例如获取数据.从文档和GitHub的讨论看来,通过使用thunk中间件来实现这一点的标准方法是一个非常简单的概念但是我不确定我是否理解将执行异步状态机的责任交给redux的好处中间件,可以使用简单的独立功能.
function fetchPosts(reddit) {
return dispatch => {
dispatch(requestPosts(reddit))
return fetch(`http://www.reddit.com/r/${reddit}.json`)
.then(response => response.json())
.then(json => dispatch(receivePosts(reddit, json)))
}
}
Run Code Online (Sandbox Code Playgroud)
然后可能在ReactJS组件中可能有一个按钮,如下面的按钮.
<button onClick={() => this.props.dispatch(fetchPosts(this.props.reddit))} />
Run Code Online (Sandbox Code Playgroud)
单击此按钮会调用异步操作创建者requestPosts,该函数返回接受调度的函数,并负责执行任何可能具有副作用的异步代码,并调度可能导致的真实操作.
虽然以上内容完全可以理解,但不清楚为什么人们不愿意做一些稍微简单化的事情,如下例所示.
function fetchPosts(dispatch, reddit) {
dispatch(requestPosts(reddit))
return fetch(`http://www.reddit.com/r/${reddit}.json`)
.then(response => response.json())
.then(json => dispatch(receivePosts(reddit, json)))
}
Run Code Online (Sandbox Code Playgroud)
<button onClick={() => fetchPosts(this.props.dispatch, this.props.reddit)} />
Run Code Online (Sandbox Code Playgroud)
基于这两个示例,我并没有看到使用thunk中间件的异步动作创建者如何购买任何东西,它需要在设置middlware时增加复杂性并引入两种动作创建者(1)返回单个的纯函数要发送的动作(2)不正确的功能,将动作和其他可能的响应反馈给调度员.我觉得我在这里遗漏的东西可以解释在redux中调度除了不可变动作之外的其他东西的好处.
我想知道我在 ReactNative/Redux 应用程序中所做的是否是错误的。这就是我处理异步操作的方式。
我的组件.js
componentDidMount() {
fetch('https://www.mywebsite.com')
.then(data => this.props.handleApiSuccess(data)) // injected as props by Redux
.catch(err => this.props.handleApiError(err)); // injected as props by Redux
}
Run Code Online (Sandbox Code Playgroud)
我可能应该做的 redux-thunk 方式
export const handleApiCall = () => dispatch => {
fetch('https://www.mywebsite.com')
.then(data => dispatch(handleApiSuccess(data)))
.catch(err => dispatch(handleApiError(err)));
}
Run Code Online (Sandbox Code Playgroud)
第一部分的做法有什么问题吗?
我有以下搜索组件
import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import { search } from '../../actions/actions'
class Search extends Component {
render() {
const {handleSubmit, "fields":{query}} = this.props;
return (
<div>
<form onSubmit={handleSubmit(search)}>
<Field className='searchInput' name="query" component="input" type="text" placeholder="Enter course name"/>
<button className='searchSubmit' type='submit' >Search</button>
</form>
</div>
);
}
}
export default reduxForm({
"form":"searchForm",
"fields":["query"]
}, null, {search})(Search);
Run Code Online (Sandbox Code Playgroud)
我的搜索动作是这样的
search : function(query){
var data = {
ep:"EP_SEARCH",
payload:{
query: query.query
}
}
getAsynch(data).then(function(result){
return {type: …
Run Code Online (Sandbox Code Playgroud) 所以我可能问错了问题,所以请留下评论,我会调整。另一位开发人员告诉我,在使用 时redux
,我应该在其中执行所有 API 调用actions
并reducers
为它们创建。但我觉得有时直接在组件中进行调用会为我节省大量代码。这种事情有最佳实践吗?
redux ×8
javascript ×7
reactjs ×7
redux-thunk ×6
react-redux ×3
asynchronous ×1
flux ×1
react-native ×1
redux-form ×1
redux-saga ×1
timeout ×1
typescript ×1