diff --git a/docs/rules/no-did-mount-set-state.md b/docs/rules/no-did-mount-set-state.md index c3c946d88e..b8ac8b1f66 100644 --- a/docs/rules/no-did-mount-set-state.md +++ b/docs/rules/no-did-mount-set-state.md @@ -49,6 +49,20 @@ var Hello = createReactClass({ }); ``` +```jsx +var Hello = createReactClass({ + componentDidMount: async function() { + const newName = await getName(); + this.setState({ + name: newName + }); + }, + render: function() { + return
Hello {this.state.name}
; + } +}); +``` + ## Rule Options ```js diff --git a/lib/util/makeNoMethodSetStateRule.js b/lib/util/makeNoMethodSetStateRule.js index f885dab715..6043bb9476 100644 --- a/lib/util/makeNoMethodSetStateRule.js +++ b/lib/util/makeNoMethodSetStateRule.js @@ -40,6 +40,11 @@ function makeNoMethodSetStateRule(methodName, shouldCheckUnsafeCb) { return false; } + function hasAsyncBefore(ancestor, callee) { + return context.getTokensBetween(context.getFirstToken(ancestor), callee) + .filter(token => token.value === 'await').length; + } + // -------------------------------------------------------------------------- // Public // -------------------------------------------------------------------------- @@ -69,6 +74,9 @@ function makeNoMethodSetStateRule(methodName, shouldCheckUnsafeCb) { ) { continue; } + if (ancestor.value.async && hasAsyncBefore(ancestor, callee)) { + continue; + } context.report({ node: callee, message: `Do not use setState in ${ancestor.key.name}` diff --git a/tests/lib/rules/no-did-mount-set-state.js b/tests/lib/rules/no-did-mount-set-state.js index ae03823018..e9563470b0 100644 --- a/tests/lib/rules/no-did-mount-set-state.js +++ b/tests/lib/rules/no-did-mount-set-state.js @@ -77,6 +77,18 @@ ruleTester.run('no-did-mount-set-state', rule, { }); `, parser: 'babel-eslint' + }, { + code: ` + var Hello = createReactClass({ + componentDidMount: async function() { + const data = await getFromServer(this.props); + this.setState({ + data: data + }); + } + }); + `, + parser: 'babel-eslint' }], invalid: [{ @@ -225,5 +237,23 @@ ruleTester.run('no-did-mount-set-state', rule, { errors: [{ message: 'Do not use setState in componentDidMount' }] + }, { + code: ` + var Hello = createReactClass({ + componentDidMount: async function() { + this.setState({ + loading: true + }); + const data = await getFromServer(this.props); + this.setState({ + loading: false, + data: data + }); + } + }); + `, + errors: [{ + message: 'Do not use setState in componentDidMount' + }] }] });