React服务器端渲染器省略了setState回调函数?

时间:2017-10-17 15:45:21

标签: reactjs serverside-rendering gatsby

我尝试使用setState的第二个参数来传递回调函数,但是(我可以收集的)看起来服务器端渲染器完全忽略了这个参数。我使用Gatsby利用服务器端渲染来构建静态的基于React的站点。我的电话是onChange处理程序,看起来像这样:

this.setState({ [event.target.name]: event.target.value }, () => { console.log('setState callback') })

状态按预期更新,但从不调用回调。 注意 :无论是为第一个参数传递对象还是函数,都会出现同样的问题。组件函数如下所示:

ReactComponent.prototype.setState = function (partialState, callback) {
  [...]
  this.updater.enqueueSetState(this, partialState, callback, 'setState');
};

该更新程序的方法位于ReactUpdateQueue.js根据调用堆栈),如下所示:

enqueueSetState: function (publicInstance, partialState)

我不完全理解React的构建过程,但我相信方法/文件来自源代码中的this文件:

/src/renderers/shared/server/ReactPartialRenderer.js

我可以找到定义此功能的唯一其他地方是here

/src/isomorphic/modern/class/ReactNoopUpdateQueue.js

enqueueSetState: function(
  publicInstance,
  partialState,
  callback,
  callerName,
) {
  warnNoop(publicInstance, 'setState');
}

看起来像是正确的方法签名,但在我的代码中调试setState调用时,它不会出现在调用堆栈中的任何位置。对于客户端呈现的React组件,这似乎不是问题(我尝试设置一个简单的repo来显示此问题,但它在CodePen等上似乎不可复制)我知道我可以使用componentDidUpdate来完成我需要做的事情,但是在我的实例中回调更加方便,我讨厌留下像这样未解决的谜团。 :)

1 个答案:

答案 0 :(得分:1)

嗯,我想通了,事实证明,这是一个自我造成的错误。默认的Gatsby安装使用React v15,但是我们想使用16,所以我们在package.json中添加了一个直接依赖,它内置于生成的包中。我仍然不太明白为什么上面提到的enqueueSetState版本被调用而不是正确的版本,但删除引用以做出反应(并添加gatsby-plugin-react-next,这样做只需要我们想要的将webpack指向更新的版本)解决了这个问题。

至少这是一个很好的借口,可以更熟悉React的胆量。也许这将在未来的某个时间节省其他人。