-
Notifications
You must be signed in to change notification settings - Fork 48.5k
How to maintain state between mount/unmount? #4345
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
Comments
No. The state is part of the instance. If state should be maintained then it probably doesn't belong in the component itself and should live in some data store, or the parent (and passed in as props). You could do something a little bit clever and have a |
The motivation here is to be able to push and pop components on a UINavigationController-like component. So it would be weird if some kind of drawer was open, or some forms partially filled out, and when you pop back to the form, then everything is reset. Similarly with a UITabBarController-like component. Hiding the components rather than unmounting is a viable solution. But this won't play nicely with existing code that relies on the mounting/unmounting lifecycle... |
Now that I think about it, you make a good suggestion. I think I just need a mixin like this. HiddenMixin = {
propTypes: {
hidden: React.PropTypes.bool.isRequired
},
componentWillMount: function() {
if (this.props.hidden) {
this.componentWillAppear && this.componentWillAppear()
}
},
componentWillReceiveProps: function(nextProps) {
if (this.props.hidden != nextProps.hidden) {
if (nextProps.hidden) {
this.componentWillAppear && this.componentWillAppear()
} else {
this.componentWillDisappear && this.componentWillDisappear()
}
}
}
} Then, in the render function, just check to see if it should be hidden. But this way, the component is still instantiated even if it doesnt render anything... |
But then I can't use CSSTransitionGroup to do push/pop animation... :/ |
@ccorcos If you render null as hidden, you will loose the child component state. If you need full control of internal state, you can always pull it out as per #3653 (comment) |
Hmm. Its not that I want access to the internal state from elsewhere, I just want to be able to re-mount a component with the same state as before. I'm trying to make something similar to NavVC = React.createClass({
displayName: 'NavVC',
propTypes: {
initialRoute: React.PropTypes.object.isRequired,
renderScene: React.PropTypes.func.isRequired
},
getInitialState: function() {
return {
stack: [this.renderScene(this.props.initialRoute)]
}
},
renderScene: function(route) {
this.props.renderScene(this, route)
},
push: function(route) {
component = this.renderScene(route)
stack = React.addons.update(this.state.stack, {$push:component})
this.setState({stack: stack})
},
pop: function() {
last = this.state.stack.length - 1
stack = React.addons.update(this.state.stack, {$splice:[[last, 1]]})
this.setState({stack: stack})
},
render: function() {
last = this.state.stack.length - 1
return this.state.stack[last]
}
}) We can wrap what is rendered in a CSSTransitionGroup to animate it as well. But the problem is, the state of the view is lost when you push a new view and the pop it... Apparently you can't keep an instantiated component and remount it though so I'm working on some other ideas. |
If you can get/set the 'internal' state, you can save it in your component/application, and use it to restore the child component tree whenever you want. It's the fully general/flexible solution, but requires a little extra work. |
@jimfb on a similar note to the above, is there any reason why |
Yeah, so I came up with way of saving and restoring the state. http://jsfiddle.net/ccorcos/t86axd6L/ The nice thing is that it can be instantiated as a prop, the pushed to the navVC. Then we don't have to worry about it ever again... |
I was also experimenting with a solution. My results are outlined in this Stack Overflow post. |
So I think there are two solution with different perspectives -- I still havent come to a conclusion on which i like more.
|
If anyone is looking for a solution. Just use a variable outside the function like:
Its an old topic but maybe usefull to anyone |
I've made a small library to deal with this, it allows you to write code like componentDidMount() {
// Restore the component state as it was stored for key '3' in section 'page'
//
// You can choose 'section' and 'key' freely, of course.
this.setState(this.props.componentstate.get('page', 3))
}
componentDidUnmount() {
// store this state's component in section 'page' with key '3'
this.props.componentstate.set('page', 3, this.state)
} which would be useful for a number of use cases, for example multi-page forms. Hope it is of use to someone. |
Excuse me for barging in :) |
I'm not really getting the answer I'm looking for on StackOverflow so I thought I'd try here.
Is it possible to instantiate a component, then mount, unmount, and remount it allowing the component to maintain its internal state/context?
The text was updated successfully, but these errors were encountered: