我已经开始学习Facebook的Flux架构了.我正在尝试制作一个简单的登录屏幕.我已经关注了flux-chat示例应用程序来创建屏幕.我有一个ServerActionCreator和WebAPIUtils之间的循环依赖问题.请参阅下面的代码.
ServerActionCreator.js
var AppDispatcher = require('../dispatcher/AppDispatcher');
var Constants = require('../constants/Constants');
var WebAPIUtils = require('../utils/WebAPIUtils');
var ActionTypes = Constants.ActionTypes;
module.exports = {
receiveLoginStatus: function(status){
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVE_LOGIN_STATUS,
status: status
});
},
loginSubmit: function(data){
WebAPIUtils.login(data);
}
}
Run Code Online (Sandbox Code Playgroud)
WebAPIUtils.js
var ServerActionCreator = require('../actions/ServerActionCreator');
module.exports = {
login: function (data) {
//Mock server API call
var status = JSON.parse('{"status":"success"}');
ServerActionCreator.receiveLoginStatus(status);
}
};
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,ServerActionCreator依赖于WebAPIUtils,而WebAPIUtils依赖于ServerActionCreator.
我认为,由于循环依赖,WebAPIUtils变成一个空对象,并且当调用ServerActionCreator中的loginSubmit函数时,我得到"未定义不是函数"错误.截图如下.

如何处理这种情况?还是有其他办法吗?任何帮助深表感谢.
这是一个使用Backbone和React 的例子.
他定义了一个Model:var _todos = new Backbone.Model();
然后添加两个函数:
var TodoStore = _.extend(_todos, {
areAllComplete: function() {
return _.every(_todos.keys(), function(id){
return _todos.get(id).complete;
});
},
getAll: function() {
return _todos.toJSON();
}
});
Run Code Online (Sandbox Code Playgroud)
我不明白为什么areAllComplete被应用于a Model而不是a Collection.
这不应该是一个Collection能够获得所有模型并检查该complete属性的函数.
同样,我希望getAll属于Collection- 获得所有模型.
这个例子似乎取代Collection有Model.
也许我不完全了解模型的使用方式.
所以我有一个很重要的组成部分:
<form>
<FirstComponent value={this.state.firstValue}/>
<SecondComponent value={this.state.secondValue}/>
{more components here}
<input type="submit" ... />
</form>
Run Code Online (Sandbox Code Playgroud)
这种形式的组件使用监听一个商店更新它的值firstAction,secondAction等
注意:组件根据返回的store.getState()更新其状态 {firstValue: something, secondValue: something, etc}
所以让我们说我FirstComponent是一个输入:
<input type="text" value={this.props.value}
onChange={(e)=>this.props.firstAction(e.target.value)}
</input>
Run Code Online (Sandbox Code Playgroud)
好的,所以onChange触发了支柱firstAction,它实际上是Flux动作,它将更新我的商店并使表格重新渲染.我有两个好东西,当用户提交表单时,我可以检查我的商店中的FirstComponent的值,并且我还控制来自父组件的所有状态.
但是,onChange每次用户键入一个字符时,此回调将调用一个操作(因此它可以产生大量调用,因此重新渲染)< - 这会引发严重的性能问题吗?
相反,我可以使用refs,当用户按下提交按钮时,获取this.refs.myFirstComponent.state...我也将获得该值(这将是不受控制的组件?)但这听起来不像社区的推荐.
所以我的问题是,上面描述的第一种方法是一个很好的方法吗?我该如何优化它?那么只应该影响FirstComponent的重新渲染不会使SecondComponent等重新渲染?是shouldComponentUpdate唯一的出路吗?
编辑1:
第一种方法我面临一个问题......我使用WebdriverIO进行e2e测试,在文本字段中添加一个值:http://webdriver.io/api/action/setValue.html
我不知道为什么,但如果我试图在输入中添加"测试"这个词,webdriver只会添加最后一个字母.如果不使用状态/存储,这个问题就消失了.但是,如果我在内部拥有状态FirstComponent,例如:
<input type="text" value={this.state.value}
onChange={(e)=>this.setState({firstValue: e.target.value})}
onBlur={()=>this.props.callback(this.state.firstValue)}
</input>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,组件在键入时似乎反应更快(仅渲染自身),然后,当用户移除焦点时,它会更新商店.我不得不说,我不喜欢这种方法,因为它不遵循你的状态(我觉得我复制状态)的模式但是它似乎工作得更快更重要:我的e2e测试工作.还有什么想法吗?
几个星期前我开始使用react-native.对于我的第一个应用程序,我使用导航器进行导航,其导航栏组件显示标题和左/右侧按钮.在阅读之后,facebook已经放弃了对导航器的支持并开发了航空实验或导航-rfc(将调用' NavExp '使其缩短),我正在尝试使用NavExp.但我无法理解它.
应用程序菜单:Android的DrawerLayout,IOS的TabIOS.并且将具有导航栏以根据内容显示标题和右侧(内容特定菜单 - 打印,复制)/左(用于菜单)按钮.
我有一个带有像这样的通量存储的多步骤反应形式:
// MultiForm.js
....
import LoadFile from './components/LoadFile';
import LoadPeople from './components/LoadPeople';
import Confirmation from './components/Confirmation';
class MultiForm extends Component {
.
.
.
nextPage() {
// Update page number with a flux action
MultiStepActions.nextPage();
}
previousPage() {
// Update page number with a flux action
MultiStepActions.previousPage();
}
render() {
const {pagina} = this.state;
<div className="container">
{page === 1 && <LoadFile
handleChange={this.handleChange}
file={this.state.file}
nextPage={this.nextPage}
data1={this.state.data1}
data2={this.state.data2}
data3={this.state.data3}/>
}
{page === 2 && <LoadPeople
listPeople={this.state.listPeople}
nextPage={this.nextPage}
previousPage={this.previousPage}
handleChangePeople={this.handleChangePeople}/>
}
{page === …Run Code Online (Sandbox Code Playgroud) 下面的代码不起作用并返回 403 forbidden 但相同的 url 提供了正确的响应邮递员工具。
fetch('https://example.com/', {
method: 'POST',
headers: {'Content-Type': 'application/json', },
body:JSON.stringify(sampledata),
}).then(result => console.log('success====:', result))
.catch(error => console.log('error============:', error));
Run Code Online (Sandbox Code Playgroud) 我正在使用MartyJS构建一个Flux应用程序(它非常接近"vanilla"Flux并使用相同的底层调度程序).它包含具有固有依赖关系的商店.例如,a UserStore跟踪当前用户,以及InstanceStore跟踪当前用户拥有的数据实例.实例数据是异步从API获取的.
问题是如何处理InstanceStore用户更改时的状态.
我开始相信(例如,阅读@fisherwebdev在SO上的答案),最适合在动作创建者函数中发出AJAX请求,并在动作中产生AJAX"成功"结果,从而导致商店发生变化.
因此,为了获取用户(即登录),我正在动作创建者函数中进行AJAX调用,当它结算时,我RECEIVE_USER将作为有效负载向用户发送动作.在UserStore这个监听并相应地更新其状态.
但是,InstanceStore如果用户更改,我还需要重新获取所有数据.
选项1:我可以RECEIVE_USER在其中监听InstanceStore,如果是新用户,则触发AJAX请求,该请求又创建另一个动作,从而导致InstanceStore更新.这个问题就是它感觉像是级联动作,虽然技术上它是异步的,所以调度员可能会允许它.
选项2:另一种方式是InstanceStore听取发出的变化事件UserStore并进行请求 - 动作舞蹈,但这也是错误的.
选项3:第三种方式是动作创建者编排两个AJAX调用并分别发送这两个动作.但是,现在动作创建者必须知道很多关于商店如何相互关联的信息.
在Flux应用程序中应该在哪里进行ajax请求?让我觉得选项1是正确的,但Flux文档也暗示商店触发行动并不好.
我已经找到了很多有关如何获取React和Flux数据的资源,博客和意见,但更不用说将数据写入服务器了.有人可以在构建一个持续更改RESTful Web API的简单编辑表单的上下文中提供"首选"方法的基本原理和一些示例代码吗?
具体来说,哪个Flux盒子应该调用$.post,ActionCreator.receiveItem()调用的位置(以及它做什么),以及商店注册方法中的内容是什么?
相关链接:
我正在学习Flux,我想我理解了工作流程:
View -> Action -> Dispatcher -> Store -> View
Run Code Online (Sandbox Code Playgroud)
但是,我不太明白我应该在哪里填充我的商店的初始状态.
例如,假设我正在编辑联系人.所以我假设我有一个ContactsStore.这是我想象在访问URL时会发生的事情/contacts/edit/23:
ContactsStore填充了我正在编辑的联系人,在这种情况下,请联系23.数据将来自服务器.EditContact视图将从收到通知ContactsStore,所以它会呈现本身在初始状态下.SaveContact操作并且流程将继续.步骤(1)对我来说不清楚.ContactsStore预计将在哪里填充初始状态?我在哪里打电话给服务器?它在商店吗?
谢谢.
我的app结构如下(HighOrderComponent是Alt的AltContainer包装器):
<App>
<HighOrderComponent store={someStore...}>
<MyCanvasComponent ref="canvasRef" />
</HighOrderComponent>
</App>
Run Code Online (Sandbox Code Playgroud)
我需要公开一个collectData()方法,MyCanvasComponent因为一旦在App组件中单击按钮,画布需要将其内容转换为base64图像.
我想,在button的click处理程序,才能够使用this.refs.canvasRef.collectData().
不幸的是,似乎refs没有考虑嵌套组件.我知道一般refs应该被认为是私人的(即属于HighOrderComponent)但是 -
它们也不可用,这意味着如果我分配一个ref="highOrderComponentRef"然后this.refs.highOrderComponentRef会工作但this.refs.highOrderComponentRef.refs.canvasRef不会.
这HighOrderComponent是一个通用组件,因此不知道它的孩子会是什么.
该this.props.children上HighOrderComponent是ReactElement轻量且不会暴露自己的方法类型.
到目前为止唯一的解决方案是传递MyCanvasComponent一个回调函数,它将自己发送一个回调函数并保存一个引用,但是根据React 0.13发行说明,这很乏味且反对最佳实践
ref resolution命令稍有改动,以便在调用componentDidMount方法后立即获得组件的引用; 只有当组件在componentDidMount中调用父组件的回调时,才应该观察到这种变化,这是一种反模式,无论如何都应该避免
reactjs-flux ×10
reactjs ×7
flux ×5
javascript ×4
ajax ×1
backbone.js ×1
browserify ×1
forms ×1
navigation ×1
react-native ×1
react-redux ×1
react-router ×1