this.setState 是不是在反应中返回承诺
Posted
技术标签:
【中文标题】this.setState 是不是在反应中返回承诺【英文标题】:Does this.setState return promise in reactthis.setState 是否在反应中返回承诺 【发布时间】:2019-04-23 20:39:25 【问题描述】:我使我的componentWillMount()
异步。现在我可以使用await
和setState
。
这里是示例代码:
componentWillMount = async() =>
const fetchRooms = this.props
await this.setState( )
fetchRooms()
所以这里的问题是 this.setState
返回承诺,因为我可以使用 await
吗?
编辑
当我放置 await 时,它会按顺序运行 1, 2, 3
而当我删除 await 时,它会运行 1, 3, 2
??
componentWillMount = async() =>
const fetchRooms = this.props
console.log(1)
await this.setState( =>
console.log(2)
)
console.log(3)
fetchRooms()
【问题讨论】:
setState
不会返回承诺,但您的代码在没有await
之前应该可以正常工作。你想达到什么目的?您还可以使 componentWillMount
方法异步,而不是为每个实例创建一个属性。 async componentWillMount() ...
***.com/questions/53080701/…的可能重复
【参考方案1】:
回答这个问题的更简单方法是我们可以使用 node.js 的预安装 util
库中的 promisify
函数,然后将其与 await 关键字一起使用。
import promisify from 'util';
updateState = promisify(this.setState);
await this.updateState( image: data );
【讨论】:
【参考方案2】:setState
通常不与 Promise 一起使用,因为很少有这种需要。如果在状态更新 (fetchRooms
) 之后调用的方法依赖于更新的状态 (roomId
),它可以通过其他方式访问它,例如作为参数。
setState
使用回调并且不返回承诺。由于这很少需要,因此创建未使用的 Promise 会导致开销。
为了返回一个承诺,setState
可以被承诺,正如this answer 中所建议的那样。
发布的代码适用于 await
,因为它是一种 hack。 await ...
是 Promise.resolve(...).then(...)
的语法糖。 await
产生一个滴答延迟,允许在状态更新完成后评估下一行,这允许按预期顺序评估代码。这与:
this.setState( roomId: room && room.roomId ? room.roomId : 0 , () =>
console.log(2)
)
setTimeout(() =>
console.log(3)
);
无法保证订单在不同条件下保持不变。此外,第一个 setState
回调不是检查状态是否更新的合适位置,这是第二个回调的用途。
【讨论】:
在我看来,对 setState 的承诺的主要需求是主观的:.then 语法非常优雅且易于理解。 (超过第二个可调用的更新后参数) @Xmanoux 它看起来很整洁,但如果它是无意的,一滴滴延迟会干扰 React 生命周期。在 1 个滴答声中可能会发生很多事情。更具体地说,可以卸载组件(这将在 OP 中发生,因为 componentWillMount 不应该是异步的)。通常,promise 控制流存在一个已知问题,因为 promise 不可取消且不了解组件生命周期。如果在不需要的地方使用 Promise,它就会变得更加突出。【参考方案3】:您可以承诺 this.setState
以便您可以将 React API 用作承诺。这就是我让它工作的方式:
class LyricsGrid extends Component
setAsyncState = (newState) =>
new Promise((resolve) => this.setState(newState, resolve));
稍后,我使用标准 Promise API 调用 this.setAsyncState
:
this.setAsyncState( lyricsCorpus, matrix, count )
.then(foo1)
.then(foo2)
.catch(err => console.error(err))
【讨论】:
您不必绑定箭头函数方法,因此您甚至不需要手动编写构造函数。它们会自动捕获周围上下文的 this。 他们没有内部this,所以它只使用外部this 警告:来自 useState() 和 useReducer() Hooks 的状态更新不支持第二个回调参数。要在渲染后执行副作用,请在组件主体中使用 useEffect() 声明它。【参考方案4】:不要认为setState
会返回Promise
,但您始终可以这样做
await new Promise( ( resolve ) =>
this.setState(
data:null,
, resolve )
)
或者你可以做一些这样的实用功能
const setStateAsync = ( obj, state ) =>
return new Promise( ( resolve ) =>
obj.setState( state , resolve )
)
并像这样在 React.Component 中使用它:
await setStateAsync(this,some:'any')
【讨论】:
【参考方案5】:你可以简单地为 setState 自定义一个 Promise
componentWillMount = async () =>
console.log(1);
await this.setRooms();
console.log(3);
;
setRooms = () =>
const fetchRooms = this.props;
return fetchRooms().then(( room ) =>
this.setState( roomId: room && room.roomId ? room.roomId : 0 , _ =>
console.log(2)
);
);
;
或者
setRooms = async () =>
const fetchRooms = this.props;
const room = await fetchRooms();
return new Promise(resolve =>
this.setState( roomId: room && room.roomId ? room.roomId : 0 , _ =>
resolve()
);
);
;
希望这个帮助=D
【讨论】:
【参考方案6】:setState 不返回承诺。
setState 有一个回调。
this.setState(
...this.state,
key: value,
, () =>
//finished
);
【讨论】:
如果使用钩子,setState 没有回调。 @HasanSefaOzalp 但是你可以使用effect
。
警告:来自 useState() 和 useReducer() Hooks 的状态更新不支持第二个回调参数。要在渲染后执行副作用,请在组件主体中使用 useEffect() 声明它。
@Danish 我的回答是关于基于分类的组件而不是钩子。【参考方案7】:
它不返回承诺。
您可以在任何表达式前面加上await
关键字。如果该表达式的计算结果不是一个 Promise,它就没有效果。
setState
接受回调。
【讨论】:
不,我可以看到变化。让我再次澄清你的问题。当我将await
放在this.setState
前面时,它会停止代码。我通过在this.setState
之前和之后放置日志来检查它。这就是我在这里提出问题的原因。以上是关于this.setState 是不是在反应中返回承诺的主要内容,如果未能解决你的问题,请参考以下文章