-
-
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
Connect runs after componentWillUnmount #351
Comments
Ah, good point, thanks. |
Hmm, no, I can’t reproduce it. I added a test confirming Do you mind providing a reproducible test case showing otherwise? |
The issue can be reproduced when you have a child component which fetched by parent. @connect(null)
export default class Parent extends React.Component {
componentWillMount() {
this.props.dispatch(fetch());
}
componentWillUnmount() {
this.props.dispatch(clean())
}
render() {
return <Child />
};
}
@connect(state => ({ profile: state.test.data.profile }))
class Child extends React.Component {
render() {
return (
<div className="container">
Hello {this.props.profile.test1} {this.props.profile.test2}
</div>
);
};
} Simple actions: export function fetch() { return { type: 'fetch' } }
export function clean() { return { type: 'clean'} } Reducers: function initializeState() {
return {
data: null
}
}
export default function test(state = initializeState(), action = {}) {
switch (action.type) {
case 'fetch':
return Object.assign({}, state, {data: {profile: {test1: 'John', test2: 'Little'}}});
case 'clean':
return Object.assign({}, state, {data: null});
default:
return state;
}
} |
I’d really appreciate if you could fold this into a standalone project on GitHub. Thanks! |
I tried adding this test based on your sample: it.only('whatever', () => {
function reducer(state = { data: null }, action) {
switch (action.type) {
case 'fetch':
return { data: { something: 42 } }
case 'clean':
return { data: null }
default:
return state
}
}
@connect(null)
class Parent extends React.Component {
componentWillMount() {
this.props.dispatch({ type: 'fetch '})
}
componentWillUnmount() {
this.props.dispatch({ type: 'clean' })
}
render() {
return <Child />
}
}
@connect(state => ({ something: state.data.something }))
class Child extends React.Component {
render() {
return null
}
}
const store = createStore(reducer)
const div = document.createElement('div')
ReactDOM.render(
<ProviderMock store={store}>
<Parent />
</ProviderMock>,
div
)
ReactDOM.unmountComponentAtNode(div)
}) For me, it fails consistently in 4.4.4, 4.4.3, and 4.4.0. |
Able to reproduce with a slightly different test case. Looking into it. |
Should be fixed in 4.4.5. |
Thank for the quick fix. Sorry that I was not able to make a test projects in time and you did it by yourself. |
No problem. |
I don't understand what was changed but 4.4.4 and 4.4.5 breaks my current solution :) import React, { Component } from 'react';
import { connect } from 'react-redux';
import { setLocale } from '../../actions/app';
import CSSModules from 'react-css-modules';
import { FormattedMessage, injectIntl } from 'react-intl';
import styles from './styles/index.local.css';
@CSSModules(styles, {
allowMultiple: true
})
class SettingsPage extends Component {
render() {
const { locale, setLocale,
intl: { formatMessage }
} = this.props;
return (
<div styleName="wrapper">
<div styleName="display-1 page-header">
<FormattedMessage id="pages.settings.title"></FormattedMessage>
</div>
<form className="form-horizontal">
<div className="form-group">
<lable className="col-sm-1 control-label">
<FormattedMessage id="pages.settings.language"></FormattedMessage>
</lable>
<div className="col-sm-2">
<select ref="select" className="form-control"
onChange={ () => setLocale(this.refs.select.value) }
value={ locale }
>
<option value="en">English</option>
<option value="ru">Русский</option>
</select>
</div>
</div>
<div className="form-group">
<lable className="col-sm-1 control-label">
<FormattedMessage id="pages.settings.theme"></FormattedMessage>
</lable>
<div className="col-sm-2">
<select className="form-control">
<option>
{ formatMessage({id: 'pages.settings.theme.dark'}) }
</option>
<option>
{ formatMessage({id: 'pages.settings.theme.light'}) }
</option>
</select>
</div>
</div>
</form>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
locale: state.getIn(['app', 'locale']),
}
}
export default connect(mapStateToProps, {
setLocale,
})(injectIntl(SettingsPage)); @gaearon thx |
const mapStateToProps = (state, own) => {
console.log(state.getIn(['app', 'locale']))
return {
locale: state.getIn(['app', 'locale']),
}
} and render() {
const { locale, setLocale,
intl: { formatMessage }
} = this.props;
console.log('locale', locale) in both locale is 'ru', i'm changing 'en' to 'ru' |
4.4.4 has a change that breaks my current solution.
I'm cleaning the state dispatching the action in the componentWillUnmount. It never caused Connect method invocation after unmount happend.
Next is how I'm using connect:
Tested on 4.4.1, 4.4.2, 4.4.3, 4.4.4
The text was updated successfully, but these errors were encountered: