-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove usages of async-unsafe lifecycle methods #919
Changes from 3 commits
7b4e162
6ad378b
20de413
94f0b8a
9ee1a36
7344f3d
a7ba298
27b2d4b
48c8a75
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -156,11 +156,10 @@ export default function connectAdvanced( | |
if (this.selector.shouldComponentUpdate) this.forceUpdate() | ||
} | ||
|
||
componentWillReceiveProps(nextProps) { | ||
this.selector.run(nextProps) | ||
} | ||
|
||
shouldComponentUpdate() { | ||
shouldComponentUpdate(nextProps) { | ||
if (nextProps !== this.props) { | ||
this.selector.run(nextProps) | ||
} | ||
return this.selector.shouldComponentUpdate | ||
} | ||
|
||
|
@@ -248,6 +247,10 @@ export default function connectAdvanced( | |
|
||
render() { | ||
const selector = this.selector | ||
|
||
// Handle forceUpdate | ||
if (!selector.shouldComponentUpdate) selector.run(this.props) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be handled by sCU above? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sCU doesn't run when forceUpdating |
||
|
||
selector.shouldComponentUpdate = false | ||
|
||
if (selector.error) { | ||
|
@@ -265,7 +268,7 @@ export default function connectAdvanced( | |
Connect.propTypes = contextTypes | ||
|
||
if (process.env.NODE_ENV !== 'production') { | ||
Connect.prototype.componentWillUpdate = function componentWillUpdate() { | ||
Connect.prototype.componentDidUpdate = function componentDidUpdate() { | ||
// We are hot reloading! | ||
if (this.version !== version) { | ||
this.version = version | ||
|
@@ -287,6 +290,8 @@ export default function connectAdvanced( | |
this.subscription.trySubscribe() | ||
oldListeners.forEach(listener => this.subscription.listeners.subscribe(listener)) | ||
} | ||
|
||
if (this.selector.shouldComponentUpdate) this.setState(dummyState) | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -200,7 +200,7 @@ describe('React', () => { | |
|
||
@connect(state => ({ string: state }) ) | ||
class Container extends Component { | ||
componentWillMount() { | ||
componentDidMount() { | ||
store.dispatch({ type: 'APPEND', body: 'a' }) | ||
} | ||
|
||
|
@@ -944,8 +944,8 @@ describe('React', () => { | |
|
||
@connect((state) => ({ state })) | ||
class Child extends Component { | ||
componentWillReceiveProps(nextProps) { | ||
if (nextProps.state === 'A') { | ||
componentDidMount() { | ||
if (this.props.state === 'A') { | ||
store.dispatch({ type: 'APPEND', body: 'B' }); | ||
} | ||
} | ||
|
@@ -1218,14 +1218,13 @@ describe('React', () => { | |
const store = createStore(() => ({})) | ||
|
||
function makeContainer(mapState, mapDispatch, mergeProps) { | ||
return React.createElement( | ||
@connect(mapState, mapDispatch, mergeProps) | ||
class Container extends Component { | ||
render() { | ||
return <Passthrough /> | ||
} | ||
@connect(mapState, mapDispatch, mergeProps) | ||
class Container extends Component { | ||
render() { | ||
return <Passthrough /> | ||
} | ||
) | ||
} | ||
return React.createElement(Container) | ||
} | ||
|
||
function AwesomeMap() { } | ||
|
@@ -1928,7 +1927,7 @@ describe('React', () => { | |
|
||
@connect(mapStateFactory) | ||
class Container extends Component { | ||
componentWillUpdate() { | ||
componentDidUpdate() { | ||
updatedCount++ | ||
} | ||
render() { | ||
|
@@ -2009,7 +2008,7 @@ describe('React', () => { | |
|
||
@connect(null, mapDispatchFactory, mergeParentDispatch) | ||
class Passthrough extends Component { | ||
componentWillUpdate() { | ||
componentDIdUpdate() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a typo here? componentDIdUpdate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will fix & add test There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just commited a fix for you. |
||
updatedCount++ | ||
} | ||
render() { | ||
|
@@ -2121,7 +2120,7 @@ describe('React', () => { | |
|
||
@connect(null) | ||
class Parent extends React.Component { | ||
componentWillMount() { | ||
UNSAFE_componentWillMount() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I tried to change it to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What error did you get with cDM? The cWM function is not consequential here anyways; this is testing for unmount cleanups. So, I'd be fine with removing it and putting a dispatch outside of the ReactDOM.render. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
this.props.dispatch({ type: 'fetch' }) | ||
} | ||
|
||
|
@@ -2324,5 +2323,27 @@ describe('React', () => { | |
expect(mapStateToPropsC).toHaveBeenCalledTimes(2) | ||
expect(mapStateToPropsD).toHaveBeenCalledTimes(2) | ||
}) | ||
|
||
it('works in <StrictMode> without warnings', () => { | ||
const spy = jest.spyOn(console, 'error').mockImplementation(() => {}) | ||
const store = createStore(stringBuilder) | ||
|
||
@connect(state => ({ string: state }) ) | ||
class Container extends Component { | ||
render() { | ||
return <Passthrough {...this.props}/> | ||
} | ||
} | ||
|
||
TestRenderer.create( | ||
<React.StrictMode> | ||
<ProviderMock store={store}> | ||
<Container /> | ||
</ProviderMock> | ||
</React.StrictMode> | ||
) | ||
|
||
expect(spy).not.toHaveBeenCalled() | ||
}) | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like a hack with bad side effects. Can we use
getSnapshotBeforeUpdate
instead?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will try that. Is it called before sCU?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it's not: https://reactjs.org/docs/react-component.html#updating
I can try to move
selector
from field on instance to field on state, then it will be available instatic getDerivedStateFromProps