在 React.createClass 中挂钩 Reflux 存储并以正确的方式触发操作

Posted

技术标签:

【中文标题】在 React.createClass 中挂钩 Reflux 存储并以正确的方式触发操作【英文标题】:Hook Reflux store in React.createClass and trigger actions the right way 【发布时间】:2018-04-18 09:00:24 【问题描述】:

我已经尝试将 store 挂接到通过 React.createClass 定义的 react 组件中。我已经实现了全局状态,但需要进行大量重构。

我将分享相关代码并在之后继续提问。

动作

var Reflux = require('reflux');
module.exports = Reflux.createActions(['markAllRead']);

商店

var Reflux = require('reflux');
var StoreActions = require('../actions/storeActions/notifications');
var React = require('react');

module.exports = Reflux.createStore(
    init: function()
        this.listen(StoreActions.markAllRead, this.markAllRead);
        this.state = 
            unreadCount: 5
        ;
    ,
    markAllRead(count)
        this.state = 
            unreadCount: 1
         ;

        this.trigger(this.state);
    
);

标题组件

var notificationsStore = require('../stores/notifications');
getInitialState: function() 
    // this.state = ; // our store will add its own state to the component's
    // this.store = notificationsStore; // <- just assign the store class itself
    return 
        notificationsData: this.props.notificationsData,
        state: ,
        store: notificationsStore
    ;
,

内部渲染函数

<div onClick=this.toggleNotifications className='bell' id='bell'>
                                <Glyphicon glyph='bell' id='bell'></Glyphicon>
                                
                                    this.state.store.state.unreadCount > 0 ?
                                    <span className='notBadge' id='bell'><span id='bell'>this.state.store.state.unreadCount</span></span>
                                    : null
                            
                        </div>
                        <div id='notificationsPanel' className='notificationsPanel'>
                            <NotificationsList list=this.state.notificationsData.notifications clickHandler=this.clickHandler/>
                            <div className='footer notification_bar'>
                                <span className='pull-left'><a onClick=this.seeAll>See all</a></span>
                                <span className='pull-right'><a onClick=this.markAllRead>Mark all as read</a></span>
                            </div>
                        </div>

... ...

updateReadStatus: function()

    notificationsStore.markAllRead(); 
,
markAllRead: function()
    ActionsNotifications.markAllRead().then(this.updateReadStatus); // API call
,

在函数updateReadStatus 中,我手动调用了存储方法(markAllRead)。当我已经在商店里听它们时,触发动作的正确方法是什么?

其次,我目前收到的商店状态为this.state.store.state.someVariable。我怎样才能在getInitialState 或任何其他功能中让生活变得简单,只需要做this.state.someVariable? getInitialState 中注释的行在 constructor() 中很有用,但在我的 createClass() 设置中却没有

谢谢!

【问题讨论】:

【参考方案1】:

目前尚不清楚您使用的是哪个版本的 Reflux,但我会尝试为您提供一个总体概述,了解如何使这项工作发挥作用...

Reflux 是一个非常简单的通量实现,你有一个非常线性的控制流 -

组件-(调用)->动作-(handle-in)->存储-(触发器)->组件

考虑到这一点,您需要遵循一些非常简单的准则。任何组件只能使用 Action 来触发 store 中的状态更改。商店反过来必须使用trigger 函数在其状态更新时触发组件重新渲染。因此,您只需要在您的组件中调用markAllRead 方法,该方法会依次调用该操作。

关于长存储引用问题...您应该能够使用各种组件 - 存储连接机制来减少冗长。现在这将取决于您的 Reflux 版本,但以下应该可以工作 -

使用 connect mixin 让您的组件与 Store 连接,这样它不仅可以在 Store trigger 调用上重新渲染,而且还可以在给定状态变量上公开 Store 状态。一个简单的例子是 -

var HeaderComponent = React.createClass(
    mixins: [Reflux.connect(notificationStore,"notifications")],
    render: function() 
        // Use "this.state.notifications.unreadCount" etc.
    
);

希望这会有所帮助。

【讨论】:

我太忙了,无法发布更新以执行操作。回流版本是 0.3.0。其实我用过connect mixin。不知道为什么我错过了发布。长调用与在渲染通知中使用 this.notificationsState = this.state.notifications.state; 相同,并在 getInitialState 中连接到 notificationsStore。 但是,您的快捷方式的解决方案也是正确的。+1d 谢谢,如果解决方案对您有用,请考虑接受答案。

以上是关于在 React.createClass 中挂钩 Reflux 存储并以正确的方式触发操作的主要内容,如果未能解决你的问题,请参考以下文章

React.Component 与 React.createClass

React.createClass 对比 extends React.Component

React.createClass和extends Component的区别

React.createClass vs. ES6 箭头函数

Render.js 文件(电子应用程序)中的“未捕获的 TypeError:React.createClass 不是函数”

报错 _react3.default.createClass is not a function