React native 使用回调设置状态

React native 使用回调设置状态,react-native,callback,setstate,React Native,Callback,Setstate,再次编辑:在此处打开了回流问题: 编辑:setState不为setState提供任何回调。它们要求您使用组件生命周期方法来确保在运行任何代码之前设置状态。如果您需要在没有生命周期方法的组件之外使用设置状态,则无法保证状态已设置。这是由于回流是如何设置状态的。它循环所有侦听组件并调用这些组件的setState方法。如果将Reflux重构为等待所有侦听组件的setState调用完成,然后调用传递到其自己的setState方法中的回调,这可能会起作用,但可能需要对Reflux进行大量返工。我已经开始使

再次编辑:在此处打开了回流问题:

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

您可以在ReactNative中使用带有回调的setState,还是仅在React中使用?我使用下面的语法,第一个调试器被命中,但第二个调试器和控制台日志从未被命中

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

请看这里的小吃:


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

问题

该库提供了一个新的
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);
    };
 componentDidMount: function() {
            var me = this;

            _.extend(me, ListenerMethods);

            this.listenTo(listenable, function(v) {
                me.setState(_.object([key],[v]));
            });
        },
也如文件中所述

该存储将其状态存储在
this.state
属性上,并通过
this.setState()
以一种与React类本身极其相似的方式对其
状态进行变异

解决方法

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

/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);
    };
 componentDidMount: function() {
            var me = this;

            _.extend(me, ListenerMethods);

            this.listenTo(listenable, function(v) {
                me.setState(_.object([key],[v]));
            });
        },
您可以在以下步骤中使用它们

希望它能消除疑虑

编辑: 按照

在店内聆听

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);
在店外的任何地方收听

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);
以下是基于承诺的工作回调的链接

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);
    };
 componentDidMount: function() {
            var me = this;

            _.extend(me, ListenerMethods);

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

我是Reflux的ES6风格商店/组件连接的创建者。希望我能为您提供一些信息。

以下是要点:

1) 当调用
setState
时,reflow立即设置其存储状态。 回流的存储状态与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
将回调依赖组件何时都更新了它们的状态,这一想法违反了所有流量原则中最基本的一条:单向数据流

如果您的商店需要了解组件是否在做某些事情,那么您已经做错了,并且您遇到的所有问题都是根本不遵循通量的XY问题。单向数据流是主要的流量原理

这一原则的存在是有充分理由的。Flux不需要存储状态属性到组件状态属性的1:1映射。您可以将任何内容映射到任何内容,甚至可以仅使用存储的状态作为构建块,以了解如何运行自己的逻辑在组件上创建全新的状态属性。例如,在存储状态中将
加载的
转换的
作为单独的属性,但通过您自己的自定义逻辑映射到一个组件中的
加载的和转换的
属性,以及另一个组件中的
未加载或转换的
。这是通量中非常强大的一部分。但是你的建议会破坏所有这一切,因为回流无法映射人们的自定义逻辑

必须保持单向数据流;商店必须独立于使用它们的组件进行操作。没有这一点,通量的力量就会分崩离析


存储的侦听操作,组件侦听存储,从任何位置调用操作。所有基于流量的数据仅从action->store->component中流动。

它按预期工作,只是在
DOM呈现中有差异,其余与
ReactJS
相同。你能发布更多的代码或信息吗?@PritishVaidya我添加了一份点心,收集了更多信息。对我来说,这似乎是意想不到的行为。那么,这是有道理的。不过,在我的示例代码中,我是从helper类中的静态函数调用它的。有没有一种解决方法不需要安装组件,或者根本不需要安装组件?TestStore是单例的。我正在调用TestAction updateTest并传入回调。我需要将该回调作为arg传入,然后在setState完成时调用。通常,您的建议是解决此问题的正确方法,但在我的特定情况下,这仍然不起作用,因为它仍然不能保证在调用回调之前实际设置了状态。对于回流,目前无法保证,因为无法在设置状态完全完成后回调,也无法正确使用承诺。是的,非常感谢。希望他们尽快实现他们的异步行为,否则您可能会尝试迁移到reduxI,因为我已经打开了一个ISU