gpt4 book ai didi

ajax - componentWillReceiveProps 和 componentDidMount 之间的竞争条件

转载 作者:行者123 更新时间:2023-12-03 14:15:17 25 4
gpt4 key购买 nike

我有一个组件,它在 props 中获取一些数据并用它们发出 ajax 请求。

var ItemList = React.createClass({
propTypes: {
filters: React.PropTypes.object.isRequired,
},
getInitialState: function() {
return {items: []};
},
componentDidMount: function() {
this.ajaxFetchItems(this.props.filters);
},
componentWillReceiveProps: function(nextProps) {
this.ajaxFetchItems(nextProps.filters);
},
ajaxFetchItems: function(filter) {
....
this.setState({items: data});
}
}

问题在于 props 几乎是立即改变的,有时 componentDidMount 中的 ajax 调用比 componentWillReceiveProps 中的稍慢,因此写入了初始状态第一次更新后。

如何避免缓慢的 componentDidMount 覆盖快速的 componentWillReceiveProps?

有更好的方法来处理下载数据的 React 组件的生命周期吗?

最佳答案

您可以在最新处理的更新状态中添加时间戳。并以某种方式确保原始 Ajax 请求的时间戳包含在 Ajax 结果中。

并添加一个 shouldComponentUpdate() 来检查接收到的结果的时间戳是否晚于状态中的时间戳。如果不是:返回 false,您的组件将忽略结果。

顺便说一句:componentDidMountcomponentWillReceiveProps 根据定义只能按该顺序运行。我怀疑您的第一个 Ajax 调用需要很长时间才能返回结果,而您的第二个调用则很快。因此您会以错误的顺序返回 Ajax 结果。(不是由于 react 缓慢的函数)。

更新:使用 shouldComponentUpdate 是处理这种情况的 react 方式:其目的是允许将新状态与旧状态进行比较,并基于该比较,而不是重新渲染。

问题(很可能)是由 ajax 响应的进入顺序产生的:

  1. Ajax 调用 1(在此示例中在 componentDidMount 中触发)
  2. Ajax 调用 2(在 componentWillReceiveProps 中触发,由组件的父级触发)
  3. 收到来自通话 2 的响应
  4. 来自调用 1 的响应收到。

因此,一个更通用的问题/解决方案是“如何处理以错误顺序返回的 ajax 响应”。

时间戳(在 shouldComponentUpdate 中)是一种方法。

另一种方法(描述为 here )是让第二个请求(在 componentWillReceiveProps 中)中止第一个 ajax 请求。

重访:经过进一步思考(componentDidMount 和 componentWillReceiveProps 中的调用感觉不对),处理组件的更通用的类似 react 的方式可能如下:

您的组件的工作基本上是:

  • 通过 prop 接收过滤器,
  • 使用过滤器通过ajax获取列表,
  • 并渲染 ajax reponse = list。

所以它有 2 个输入:

  • 过滤器(= prop)
  • 列表(= ajax 响应)

并且只有 1 个输出 = 列表(可能为空)。

工作原理:

  • 组件第一次接收filter作为prop:它需要发送ajax请求,并渲染一个空列表或某种加载状态。
  • 所有后续过滤器:组件应发送新的 ajax 请求(并终止可能未完成的旧请求),并且不应重新渲染(!)
  • 每当收到 ajax 响应时,它都应该重新呈现列表(通过更新状态)。

使用 React 设置它可能看起来像这样:

getInitialState() {
this.fetchAjax(this.props.filter); // initiate first ajax call here
return { list : [] }; // used to maybe display "loading.." message
}
componentWillReceiveProps(nextProps) {
this.fetchAjax(nextProps.filter); // send off ajax call to get new list with new filter
}
shouldComponentUpdate(nextProps, nextState) {
return (this.state.list != nextState.list); // only update component if there is a new list
// so when new props (filter) comes in there is NO rerender
}
render() {
createChildrenWith(this.state.list);
}
fetchAjax(filter) {
killOutStandingRequests(); // some procedure to kill old ajax requests
getListAsync…
request: filter // request new list with new filter
responseHandler: this.handleResponse // add responseHandler
}
responseHandler(data) {
this.setState({ list : data }); // put the new list in state, triggering render
}

状态中的原始时间戳可以解决上面发布的问题,但我想我会分享修改后的 react 组件作为奖励......

关于ajax - componentWillReceiveProps 和 componentDidMount 之间的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33482613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com