未为外部(npm 打包)组件调用 React setState 回调 [英] React setState callback not called for external (npm packaged) component

查看:32
本文介绍了未为外部(npm 打包)组件调用 React setState 回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用带有回调的 setState 以确保在状态更新后运行.

I am using setState with a callback to ensure things run after the state has been updated.

...
    this.setState({enabled : true},this.getData);
}
getData () {
    const self = this;
    fetch(this.props.url,{
        method : 'post',
        body : this.state
    }).then(function (response) {
        return response.json();
    }).then(function (result) {
        self.update();
    });
}
...

setState 正在被调用.this.state.enabled 确实更改为 true.但是,this.getData 没有被调用.

setState is getting called. this.state.enabled does change to true. However, this.getData is not getting called.

我发现有趣的一件事是,这发生在我通过 npm 包使用的组件上.在我自己的代码中,带有回调的 setState 按设计工作.

One thing I found interesting is that this is happening for a component I am using via an npm package. In my own code, setState with a callback works as designed.

所说的外部组件也是我自己打包的.我正在使用 webpack 来构建它.我的 webpack 配置可能有问题吗?

The said external component is also packaged by me. I am using webpack to build it. Might there be something wrong with my webpack config?

这是:

const Webpack = require('webpack');
const path = require('path');

module.exports = {
  entry: {
    index : './src/index.js'
  },
  output: {
    path: path.join(__dirname,'dist'),
    filename: '[name].js',
    library : 'TextField',
    libraryTarget: 'umd'
  },
  externals : [
    {
      'react' : {
        root : 'React',
        commonjs2 : 'react',
        commonjs : 'react',
        amd : 'react'
      }
    }
  ],
  module: {
      loaders: [
          { test: /\.(js?)$/, exclude: /node_modules/, loader: require.resolve('babel-loader'), query: {cacheDirectory: true, presets: ['es2015', 'react', 'stage-2']} }
      ]
  },
  devtool : 'eval'
};

所以现在我很确定当我从包中使用我的组件时,当我从我的源中使用它时,会发生一些可疑的事情.

So now I am pretty sure something fishy is going on when I use my component from a package vs, when I use it from my source.

当我从作为源代码一部分的组件调用 setState 时,这就是所谓的:

When I call setState from a component which is part of my source-code, this is what is called:

ReactComponent.prototype.setState = function (partialState, callback) {
    !(typeof partialState === 'object'
    || typeof partialState === 'function' 
    || partialState == null) ?
        process.env.NODE_ENV !== 'production' ? 
            invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.')
        : _prodInvariant('85')
    : void 0;
    this.updater.enqueueSetState(this, partialState);
    if (callback) {
        this.updater.enqueueCallback(this, callback, 'setState');
    }
};

以上来自一个名为 ReactBaseClasses.js

当我从打包为 npm 包的组件中调用 setState 时,这就是所谓的:

When I call setState from a component I packaged as an npm package, this is what is called:

Component.prototype.setState = function (partialState, callback) {
    !(typeof partialState === 'object'
      || typeof partialState === 'function'
      || partialState == null) ?
        invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.')
        : void 0;
    this.updater.enqueueSetState(this, partialState, callback, 'setState');
};

以上来自一个名为 react.development.js 的文件.注意回调被传递给 enqueueSetState.有趣的是,当我进入 enqueueSetState 时,该函数对回调不做任何事情:

The above is from a file named react.development.js. Notice that callback is passed to enqueueSetState. Interestingly, when I break into enqueueSetState, the function does nothing with the callback:

enqueueSetState: function (publicInstance, partialState) {
    if (process.env.NODE_ENV !== 'production') {
        ReactInstrumentation.debugTool.onSetState();
        process.env.NODE_ENV !== 'production' ? warning(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().') : void 0;
    }

    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState');

    if (!internalInstance) {
        return;
    }

    var queue = internalInstance._pendingStateQueue || 
    (internalInstance._pendingStateQueue = []);
    queue.push(partialState);

    enqueueUpdate(internalInstance);
},

推荐答案

这可能是 React 的一个错误.显然,结合 enqueueSetState 和 enqueueCallback 功能是一个主要的错误修复,但在早期版本的 React 中,这些是单独运行的调用.

This could be a bug with React. Apparently it was a major bug fix to combine the enqueueSetState and enqueueCallback functionality, but these were separately functioning calls in earlier versions of React.

https://github.com/facebook/react/issues/8577

在导入 npm 模块时,有时它们会引入不同版本的 React 作为依赖项,从而使用 setState 和回调创建此类不一致的错误.

When importing npm modules, sometimes they bring in different versions of React as dependencies, creating these kinds of inconsistency bugs with setState and callbacks.

https://github.com/facebook/react/issues/10320

这篇关于未为外部(npm 打包)组件调用 React setState 回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆