首页 文章

Statefull组件与可能异步的存储进行交互

提问于
浏览
1

我正在研究一个React Flux项目,其中异步交互是一个持续的事情,当涉及到反应生命周期时,我仍然有点不稳定 .

在我的有状态组件中,我有一个getStateFromStores函数,如果商店中没有状态,则返回false bool,否则返回状态 .

正如我现在所说的那样,循环如下:

我的组件中有一个名为getState()的绑定函数(ES6反应类),它只调用getStateFromStores并检查返回值是否为false,如果不是,则调用带状态的setState() .

由于状态变化的通知可以来自不同的来源,我喜欢在一个地方声明逻辑(getState)

国家变化可以来自以下方面:

  • ComponentDidMount(我应该将它移动到initialState吗?)这是组件生命周期中发生的第一件事 . (除非我们的商店已存在状态,否则我们会得到错误的回报)

  • ComponentWillReceiveProps如果在父组件中更改了状态,我们通知组件它应该使用新的props获取新状态 .

  • 存储更改侦听器当存储具有新状态时,将调用getState作为回调(虽然有点问题,因为发出的原因可能是由于给定组件的调用而导致的 - 所以我可能实现onStoreChange作为回调谁在转来电getState)

我正在玩一个叫做取物的状态道具,我可以用来控制流量,但这有问题吗? - 因为每次我更改状态时它都会触发渲染(?) - 我可以使用静态吗?

我想象下面的一些事情; DidMount触发getState(),getState设置获取为true,现在所有其他调用尝试都会因bool检查而失败 .

然后我将实现一个resetState,它将状态恢复为默认状态(获取false),然后再次触发getState .

我在“高阶组件”中抽象出所有这些功能

谢谢!

2 回答

  • 1

    我采取了不同的方法 . 我发现编写React组件的一个巨大优势是,您可以将组件视为一个独立的单元 - 具有自己的HTML,JavaScript,数据获取 - 甚至样式 . 它依靠Flux存储来跟踪数据,而不是将数据作为道具传递 .

    假设您有用户登录并收到一些信息 . 现在,假设用户想要管理他们的帐户 . 我们可以做这样的事......

    <Account user_info={this.state.user_info} />

    这样可以正常工作,但是如果账户知道user_id,那么它不能获得它需要的user_info吗?那将导致我们......

    <Account user_id={this.state.user_info.user_id}>

    但是,真的,商店不知道登录用户是谁吗?毕竟,它是获取/存储数据的必要条件 . 那么为什么不......

    <Account />

    ...让Account从商店获取所需的数据 - 不需要user_id,因为商店已经知道登录用户 .

    无论如何,只是一种不同的思考方式 .

  • 2

    我现在称之为 Controller . 它基本上就像React组件一样 - 但它的责任有点不同 .

    我认为这只是委托 . 唯一的责任是从商店获取数据(状态)并将其(作为道具)传递给其子组件,让他们完成所有工作 .

    这是通过将商店中的数据设置为 Controller 的状态来完成的 . 商店中的任何更改都会返回(仅) Controller ,后者会更新其状态 . 由于状态作为道具传递给子项,因此商店中的更改将触发使用该数据重新呈现的所有子组件(如果必须) .

    我尝试只将相关数据传递给子组件,但不要太担心它们获取大量数据(或者关于一些额外的重新渲染) .

    在实践中 Controller 看起来像这样:

    function getStateFromStores() {
        return {
            players: PlayerStore.getData(),
            cards: CardStore.getData()
        };
    }
    
    var Controller = React.createClass({
        getInitialState: function() {
            return getStateFromStores();
        },
    
        componentDidMount: function() {
            PlayerStore.addChangeListener(this._onChange);
            CardStore.addChangeListener(this._onChange);
        },
    
        componentWillUnmount: function() {
            PlayerStore.removeChangeListener(this._onChange);
            CardStore.removeChangeListener(this._onChange);
        },
    
        _onChange: function() {
            this.setState(getStateFromStores());
        },
    
        render: function() {
            return (
                <Component1 
                    players={this.state.players}
                    cards={this.state.cards}
                />
    
                <Component2
                    players={this.state.players}
                />
    
                <Component3
                    cards={this.state.players}
                />
            );
        }
    });
    
    module.exports = Controller;
    

相关问题