我已经阅读了这个答案,减少了样板,看了几个GitHub示例,甚至尝试了redux(todo apps).
据我了解,官方redux doc动机提供了与传统MVC架构相比的优点.但它没有提供问题的答案:
为什么你应该使用Redux而不是Facebook Flux?
这只是编程风格的问题:功能与非功能?或者问题是在redux方法中遵循的能力/开发工具?也许缩放?还是测试?
如果我说redux对于来自函数式语言的人来说是一种变化,我是对的吗?
要回答这个问题,您可以比较实施redux在flux和redux上的动机点的复杂性.
以下是官方redux doc动机的动机点:
我刚刚发现了Redux.一切看起来都不错.使用Redux over Flux是否有任何缺点,陷阱或妥协?谢谢
我要迁移到Redux.
我的应用程序包含很多部分(页面,组件),因此我想创建许多reducer.Redux示例显示我应该使用combineReducers()生成一个reducer.
另外据我所知,Redux应用程序应该有一个商店,并在应用程序启动后创建它.在创建商店时,我应该通过我的组合减速机.如果应用程序不是太大,这是有道理的.
但是,如果我构建多个JavaScript包怎么办?例如,每个应用程序页面都有自己的包.我认为在这种情况下,一个联合减速器并不好.我查看了Redux的来源,并找到了replaceReducer()功能.这似乎是我想要的.
replaceReducer()当我在应用程序的各个部分之间移动时,我可以为我的应用程序的每个部分创建组合的reducer .
这是一个好方法吗?
React.js的一大优势应该是服务器端渲染.问题是密钥功能React.renderComponentToString()是同步的,这使得在服务器上呈现组件层次结构时无法加载任何异步数据.
假设我有一个用于评论的通用组件,我可以在页面的任何位置删除它.它只有一个属性,某种标识符(例如文章的id在其下面放置注释),其他所有内容都由组件本身处理(加载,添加,管理注释).
我非常喜欢Flux架构,因为它使很多东西变得更容易,而且它的商店非常适合在服务器和客户端之间共享状态.一旦我的包含注释的商店被初始化,我就可以将其序列化并将其从服务器发送到客户端,在那里可以轻松恢复.
问题是填充我的商店的最佳方式是什么.在过去的几天里,我一直在谷歌搜索,我遇到了一些策略,考虑到React的这个功能被"提升"多少,这些策略看起来都不是很好.
在我看来,最简单的方法是在实际渲染开始之前填充我的所有商店.这意味着在组件层次结构之外的某个地方(例如,挂钩到我的路由器).这种方法的问题是我必须两次定义页面结构.考虑一个更复杂的页面,例如一个包含许多不同组件的博客页面(实际的博客帖子,评论,相关帖子,最新帖子,推特流......).我必须使用React组件设计页面结构,然后在其他地方我必须定义为当前页面填充每个所需存储的过程.这似乎不是一个很好的解决方案.不幸的是,大多数同构教程都是以这种方式设计的(例如,这个伟大的通量教程).
React-async.这种方法很完美.它让我只需在每个组件的特殊函数中定义如何初始化状态(无论是同步还是异步),并在层次结构呈现为HTML时调用这些函数.它的工作方式是在状态完全初始化之前不会呈现组件.问题是它需要Fibers,据我所知,这是一个改变标准JavaScript行为的Node.js扩展.虽然我非常喜欢这个结果,但在我看来,我们并没有找到解决方案,而是改变了游戏规则.而且我认为我们不应该被迫这样做来使用React.js的这个核心功能.我也不确定这个解决方案的一般支持.是否可以在标准Node.js虚拟主机上使用Fiber?
我自己在思考一点.我没有真正想过通过实现细节,但一般的想法是我会以类似于React-async的方式扩展组件,然后我会在根组件上重复调用React.renderComponentToString().在每次传递过程中,我会收集扩展回调,然后在传递和传递中调用它们来填充商店.我将重复此步骤,直到填充当前组件层次结构所需的所有存储.有很多事情需要解决,我对性能特别不确定.
我错过了什么?还有其他方法/解决方案吗?现在我正在考虑采用react-async/fiber方式,但我并不完全确定它,如第二点所述.
关于GitHub的相关讨论.显然,没有官方方法甚至解决方案.也许真正的问题是如何使用React组件.像简单的视图层(几乎是我的建议第一)或像真正的独立和独立组件?
你应该this.setState()在使用redux时使用吗?或者你应该总是派遣行动并依靠道具?
我是react.js的新手我实现了一个组件,我从服务器获取数据并使用它,如,
CallEnterprise:function(TenantId){
fetchData('http://xxx.xxx.xx.xx:8090/Enterprises?TenantId='+TenantId+' &format=json').then(function(enterprises)
{
EnterprisePerspectiveActions.getEnterprise(enterprises);
}).catch(function()
{
alert("There was some issue in API Call please contact Admin");
//ComponentAppDispatcher.handleViewAction({
// actionType: MetaItemConstants.RECEIVE_ERROR,
// error: 'There was a problem getting the enterprises'
//});
});
},
Run Code Online (Sandbox Code Playgroud)
我想将Url存储在配置文件中,所以当我在测试服务器或生产上部署它时,我只需更改配置文件中的url而不是js文件,但我不知道如何在react.js中使用配置文件
任何人都可以指导我如何实现这一目标?
我正在使用ReactJS,我的应用程序的一部分需要相当印刷的JSON.
我得到一些JSON,如:{ "foo": 1, "bar": 2 },如果我JSON.stringify(obj, null, 4)在浏览器控制台中运行它,它很漂亮,但是当我在这个反应片段中使用它时:
render: function() {
var json = this.getStateFromFlux().json;
return (
<div>
<JsonSubmitter onSubmit={this.onSubmit} />
{ JSON.stringify(json, null, 2) }
</div>
);
},
Run Code Online (Sandbox Code Playgroud)
它呈现看起来像JSON "{ \"foo\" : 2, \"bar\": 2}\n".
如何正确解释这些字符?{
Redux文档的第一个原则是:
整个应用程序的状态存储在单个存储中的对象树中.
我实际上认为我理解所有校长.但我现在很困惑应用意味着什么.
如果应用程序只是网站中一个复杂的部分,只能在一个页面中工作,我理解.但如果申请意味着整个网站怎么办?我应该使用LocalStorage或cookie或其他东西来保存状态树吗?但是如果浏览器不支持LocalStorage怎么办?
我想知道开发人员如何保持他们的状态树!:)
根据文档反应app的状态必须是可序列化的.那么课程怎么样?
假设我有一个ToDo应用程序.到目前为止,每个Todo项目都具有类似等的属性.现在我想在不可序列化的对象上使用方法.即它会重命名todo并做很多其他的东西.namedateTodo.rename()
据我所知,我可以在某处声明函数,rename(Todo)或者通过props将该函数传递this.props.rename(Todo)给组件.
我在.rename()某处声明了2个问题:1)在哪里?在减速机?would be instance在应用程序周围的reducer中找到所有方法很难.2)传递这个功能.真?我应该从所有更高级别的组件手动传递它吗?每次我有更多的方法添加大量的样板来传递它?或者总是这样做,并希望我对一种类型的对象只有一种重命名方法.不是Todo.rename() Task.rename()和Event.rename()
这对我来说似乎很愚蠢.对象应该知道可以对它做什么以及以何种方式.是不是?
我在这里缺少什么?
我一直在努力寻找解决这个问题的方法......
我正在开发一个带有在线记分牌的游戏.玩家可以随时登录和注销.完成游戏后,玩家将看到记分牌,并查看自己的排名,并自动提交分数.
记分牌显示了玩家的排名和排行榜.
当用户完成播放(提交分数)以及用户只想查看他们的排名时,使用记分板.
这是逻辑变得非常复杂的地方:
如果用户已登录,则将首先提交分数.保存新记录后,将加载记分板.
否则,将立即加载记分板.玩家将获得登录或注册的选项.之后,将提交分数,然后记分板将再次刷新.
但是,如果没有要提交的分数(只需查看高分表).在这种情况下,只需下载播放器的现有记录.但由于此操作不会影响记分牌,因此记分牌和玩家记录应同时下载.
有无限数量的级别.每个级别都有不同的记分牌.当用户查看记分板时,用户正在"观察"该记分板.当它关闭时,用户停止观察它.
用户可以随时登录和注销.如果用户注销,则用户的排名应该消失,如果用户以另一个帐户登录,则应该获取并显示该帐户的排名信息.
...但是,此信息只应针对用户当前正在观察的记分板进行.
对于查看操作,结果应缓存在内存中,以便如果用户重新订阅同一记分板,则不会提取.但是,如果提交了分数,则不应使用缓存.
任何这些网络操作都可能失败,并且播放器必须能够重试它们.
这些操作应该是原子的.所有状态都应该一次更新(没有中间状态).
目前,我能够使用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架构中,更新程序在使用形式时也会发出副作用 …