使用回调

时间:2018-04-06 21:15:02

标签: react-native callback setstate

再次编辑:在此处打开了Reflux问题:https://github.com/reflux/refluxjs/issues/544

编辑:Reflux setState不为setState提供任何回调。它们要求您使用组件生命周期方法来确保在运行任何代码之前设置状态。如果您需要在组件之外使用回流setState,而您没有生命周期方法,则无法保证设置状态。这是由于Reflux如何执行其setState。它循环所有侦听组件并调用这些组件的setState方法。如果Reflux被重构为等到所有侦听组件的setState调用完成,那么调用传递给它自己的setState方法的回调,这可能有效,但可能需要对Reflux进行大量返工。我已经开始使用单例类来管理其中的一些变量,因为它们完全在组件生命周期之外。

你可以在ReactNative中使用带有回调的setState,还是仅在React中使用?我正在使用以下语法并且第一个调试器被命中,但第二个调试器和控制台日志永远不会被命中。

编辑:在挖掘更多之后,似乎直接使用设置状态时不会发生这种情况,但只有在通过回流存储运行和/或不使用组件时才会发生。

在这里查看小吃:https://snack.expo.io/S1dm3eFoM

   debugger
    this.setState( 
          params, 
          () => {
            debugger
            console.log("CALLIN IT BACK")
          }
        )

2 个答案:

答案 0 :(得分:1)

我是Reflux的ES6风格商店/组件连接的创建者。希望我能为你阐明这一点。

这里有重点:

1)Reflux在setState次呼叫后立即设置其存储状态。

Reflux的商店状态与React没有相同的问题,也不需要React的解决方法(回调)。 保证您的更改会立即反映在商店的状态中,这就是没有回调的原因。下一行代码将反映商店的新状态。

tl; dr,无需解决方法。

// in Reflux stores this works
this.setState({foo:'foo'});
console.log(this.state.foo === 'foo') // true
this.setState({foo:'bar'});
console.log(this.state.foo === 'bar') // true

2)商店永远不会依赖于组件!

setState关于依赖组件何时全部更新其状态的回调的想法是主要违反单个最基本的所有通量原则:1路数据流。

如果您的商店需要知道组件是否正在做某事,那么您已经做错了,而您遇到的所有问题都是XY问题,从根本上说并没有跟随流量。单向数据流是主要的通量原理。

这个原则存在是有充分理由的。 Flux不需要将存储状态属性1:1映射到组件状态属性。您可以将任何内容映射到任何内容,或者甚至只使用商店的状态作为构建块,了解如何运行自己的逻辑以在组件上创建全新的状态属性。例如,将loadedtransitioned作为存储状态中的单独属性,但映射到一个组件中的loadedAndTransitioned属性,并通过您自己的自定义逻辑映射到另一个组件中的notLoadedOrTransitioned 。这是一个强大的,非常强大的通量。但是你的建议几乎会破坏所有这些,因为Reflux无法映射人们的自定义逻辑。

必须保持单向数据流;商店必须独立于使用它们的组件运行。没有这个,通量的力量就会崩溃!

Store's聆听动作,组件侦听商店,从任何地方调用动作。所有基于通量的数据都来自行动 - >商店 - >仅限组件。

答案 1 :(得分:0)

我已经检查了库refluxjs,问题和解决方法如下所述。

<强>问题

该库提供的setState新实例与ReactJS setState不完全相似,省略了回调,如下面的代码所示。

<强> /dist/reflux.js

proto.setState = function (obj) {
        // Object.assign(this.state, obj); // later turn this to Object.assign and remove loop once support is good enough
        for (var key in obj) {
            this.state[key] = obj[key];
        }
        // if there's an id (i.e. it's being tracked by the global state) then make sure to update the global state
        if (this.id) {
            Reflux.GlobalState[this.id] = this.state;
        }
        // trigger, because any component it's attached to is listening and will merge the store state into its own on a store trigger
        this.trigger(obj);
    };

同样如文档

中所述
  

该商店会将其状态存储在this.state属性上,并通过state 以与React类本身极为相似的方式改变其this.setState()

解决方法

该库提供了listener函数,这些函数为我们提供了setState ReactJS obj的回调,如下面的代码段所示。

<强> /dist/reflux.js

 componentDidMount: function() {
            var me = this;

            _.extend(me, ListenerMethods);

            this.listenTo(listenable, function(v) {
                me.setState(_.object([key],[v]));
            });
        },

您可以在以下way

中使用它们
this.listenTo(action, callback)

希望它能消除疑虑

修改 根据{{​​3}}

使用

在店内收听

constructor()
    {
        super();
        this.state = {count: 0};
        this.listenTo(increment, this.incrementItUp);
    }

incrementItUp()
    {
        var newCount = this.state.count + 1;
        this.setState({count: newCount});
    }

在商店外听音乐

// listen directly to an action
myActions.actionName.listen(myCallbackFunc);

// listen to a child action
myActions.load.completed.listen(myCallbackFunc);
  

这里是基于承诺的工作回调docs的链接