-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
can React support feature like keep-alive in Vue? #12039
Comments
Can you describe what this feature is for someone who doesn’t know Vue, and how you imagine it working in React? |
As Vue's API said:
basic usage:
so, with <keep-alive>, when user switch between pages, these pages will not be refreshed and their status will be preserved. It will give users a great experience in some scenarios like news webapp. |
+1 keep the component in cache when route to next component, act some like a stack. |
In React this is usually solved in one of the two ways:
|
@gaearon Could you please explain some details about the first-class API you mentioned? |
you can also intercept the change (prop/state change) that leads to |
@bjrmatos , your suggestion is practical. There are ways to work around. But i think they are not so perfect or clean. since when you write a component, you should concern both the React life-cycle and something like page life-cycle. Doesn't it? |
my suggestion is not a work around, it is the react way of doing things.. reacting to state/props changes and do something is the whole react model. i would say it is clean because it is the way how things should be done with react.
to me what you are describing is just a react component life-cycle concern, a component is a component no matter if it is a whole page or not and you need to use the available lifecycle hooks to do your thing, you can even create a don't know about the Vue approach but a keep alive feature in react sounds dirty, because there is the traditional way of doing the same with just reacting to changes in normal react lifecycles ( |
We’ll post it soon at https://github.com/reactjs/rfcs. Stay tuned for PRs there. |
@bjrmatos the keypoint is how the PageComponent inform its descendant component to remove event listeners except for all component has a visible prop? |
Hello @gaearon, I'm a big fan of React butI had to work with Vue at work. I'm working with Vue for months now and I still prefere React. But today I found about keep-alive and for the first time I found something better than React. Just because React does not have this feature. Anyway, I think it's something really increreble and maybe something that React could do too (I don't know). Here the doc to help you to know more about it: https://br.vuejs.org/v2/guide/components-dynamic-async.html#keep-alive-with-Dynamic-Components |
Restrictions like this sound quite artificial:
We try to avoid introducing APIs in React that work in a very limited subset of cases but then can’t work in others. This might seem “nice” at first but then you need to change the code a little bit, and hit a wall because you have to change the whole approach. Instead, we prefer a more limited set of APIs that work the same way in all circumstances. Then you can learn them once and apply the same techniques everywhere without having to tweak the code whenever you run into a limitation in some convenience shortcut. The approaches I mentioned above (either lifting state up to a parent component or hiding/showing with
This sounds like a recipe for memory leaks to me. If you keep all the components instantiated forever, your app will keep eating memory as you navigate between the pages. Just caching data alone would be okay (and that’s exactly what React lets you do), but keeping component instances and state sounds like it would create problems as the app becomes more complex (but at that point it’s too late to fix because the app heavily relies on this pattern). I don’t think we’d want to introduce APIs that encourage irresponsible memory usage into React. That said we definitely want to make the caching use case easier (as a few people rightly noted, brining in something like Redux just to cache network responses is overkill). We’re working on something for this — stay tuned for announcements. Thanks everyone for your links and the discussion! Hope my answer wasn’t too frustrating. I think the “React way” might feel annoying if you’re used to having a helper like |
Fair enough.Thank you for your explanation @gaearon. I understand... everything it's trade offs after all. |
good |
@zengjialuo @gaearon @bjrmatos @ninahaack Now, I have some doubts about the lifecycle of react-keep-alive. In the first version, I added two lifecycles This can be confusing for users, such as [Lifecycle and events] (https://codesandbox.io/s/q1xprn1qq) and [Control cache] (https://codesandbox.io/s/llp50vxnq7), via `bindLifecycle The life cycle of the component after the high-order function package will be:
I used the life cycle of the old version of React, and it would be confusing if the user used it like this; but the new life cycle may not be a problem, I am not sure. |
i hope react can support keep-alive |
I have my implementation react-activation and here is the Online Demo Because The principle is easy to say but it's not a good idea...The implementation destroys the original rendering level and brings some bad effects. Simplest Implementation as follows import React, { Component, createContext } from 'react'
const { Provider, Consumer } = createContext()
const withScope = WrappedCompoennt => props => (
<Consumer>{keep => <WrappedCompoennt {...props} keep={keep} />}</Consumer>
)
export class AliveScope extends Component {
nodes = {}
state = {}
keep = (id, children) =>
new Promise(resolve =>
this.setState(
{
[id]: { id, children }
},
() => resolve(this.nodes[id])
)
)
render() {
return (
<Provider value={this.keep}>
{this.props.children}
{Object.values(this.state).map(({ id, children }) => (
<div
key={id}
ref={node => {
this.nodes[id] = node
}}
>
{children} {/* render them into a component that will not be unloaded */}
</div>
))}
</Provider>
)
}
}
@withScope
class KeepAlive extends Component {
constructor(props) {
super(props)
this.init(props)
}
init = async ({ id, children, keep }) => {
const realContent = await keep(id, children) // extract the children in <KeepAlive>
this.placeholder.appendChild(realContent) // drag the rendered content back using the DOM operation
}
render() {
return (
<div
ref={node => {
this.placeholder = node
}}
/>
)
}
}
export default KeepAlive |
I love Vue than React, Vue is so great!! |
Sometimes it's not a good thing that brother's behavior Vue encapsulates perfectly. The best way to build it is to fit your own framework, isn't it? |
i found this issue: #4770, and @sophiebits said that React never reuses an instance after it's been unmounted.
does it means that React will never support feature like keep-alive in Vue? or there is other way to maintain component's state?
The text was updated successfully, but these errors were encountered: