-
Notifications
You must be signed in to change notification settings - Fork 106
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
未能从内嵌自定义的 Context 中使用 Consumer 读取数据 #36
Comments
是否可以尝试增加一个组件 每个 KeepAlive 可选择不同的缓存节点,Provider 作为默认驿站备用,也可以用在驿站被销毁时的 fallback 缓存节点 如上述例子中 ...
import { Provider as KeepAliveProvider, KeepAlive, KeepAliveStation } from "react-keep-alive";
...
function App() {
...
return (
<KeepAliveProvider>
...
<Provider value={1}>
<KeepAliveStation name="station-1" />
...
<KeepAlive name="Test" station="station-1">
<Consumer>
{context => <Test contextValue={context} />}
</Consumer>
</KeepAlive>
...
</Provider>
...
</KeepAliveProvider>
);
}
... 不过也许无法实现 fallback 功能,驿站销毁的话,上边挂载的缓存节点也许会强迫走 unmount 周期 这个方案也会造成 react-dev-tools 面板混乱程度的增加... |
@CJY0208 抱歉现在才回复,这个问题确实很严重,并且我认为现在的实现方式也有一些问题, |
我自己也在尝试一个简易的 keep-alive 实现,从 React 渲染流程来看,这个问题很难绕过...目前来说似乎是实现 keep-alive 的唯一途径 在实现过程中我做了一个可行的尝试: 增加 // 书写时
...
<KeepAliveProvider>
...
<Provider value={1}>
...
<KeepAlive name="Test">
<Consumer>
{context => <Test contextValue={context} />}
</Consumer>
</KeepAlive>
...
</Provider>
...
</KeepAliveProvider>
...
// 实际渲染时
...
<KeepAliveProvider>
...
<Provider value={1}>
...
<Consumer>
{context => (
<KeepAlive name="Test" contextValue={context}>
{/* render to Keeper named "Test" */}
</KeepAlive>
)}
</Consumer>
...
</Provider>
...
<Keeper name="Test">
{contextValue => (
<Provider value={contextValue}>
<Consumer>
{context => <Test contextValue={context} />}
</Consumer>
</Provider>
)}
</Keeper>
</KeepAliveProvider>
... 大概是这样子,预先声明可能需要修复的 Context 组,KeepAlive 提前做 HOC 封装,套上一层 Consumer 尝试获取可能存在的上下文,再将 KeepAlive 获取到的上下文传入其对应的 Keeper 中,重建上下文关系 后续可以尝试包装 但如果需要修复的上下文过多,dev-tools 中的层级结构会比较难看 |
@CJY0208 嗯嗯,现在所讨论的这个问题,实际上最简单的方式是可以直接放在
你说的两种方式都很有价值,但是我认为这样会有一些复杂,我也希望暴露出来的 API 能够越少越好,这样易用性会好一些。 因此我想在不改变 API 的情况下,重构下实现。 |
目前感觉是依赖于 React 层级结构的行为,可能都产生了破坏性,例如下述有两个影响 1、事件冒泡失效 https://codesandbox.io/s/basic-currently-5gfz9 function App() {
const [show, setShow] = useState(true);
const toggle = () => setShow(show => !show);
return (
<KeepAliveProvider>
<div onClick={() => {
console.log('捕获到冒泡事件')
}}>
<KeepAlive name="Test">{show && <div>random</div>}</KeepAlive>
{show && <div>random</div>}
<button onClick={toggle}>toggle</button>
</div>
</KeepAliveProvider>
)
} 猜测 Error Boundaries 也受了影响,不过还没测 |
@CJY0208 👍,这个确实是预先没有考虑到得问题 |
想学习一下是如何你是如何使用桥接,稳读了一下源码,不太懂。有两个问题,希望大佬能解决一下困惑 |
|
Hello
由于
react-keep-alive
原理大致为将KeepAlive children
提取出来渲染到<KeepAliveProvider />
节点下,而非<KeepAlive />
之下这将导致
KeepAlive
中的组件无法被React
认为是在其所处的上下文之中样例大致如下:
https://codesandbox.io/s/basic-currently-rwo9y
样例中的
<Test />
无法从<Consumer />
中获得contextValue
属性从实现原理上来说目前似乎无法避免,是不得已而为之
想问问在这方面有没有考虑其他可能的实现方式呢?
目前会对直觉上的
Context
造成破坏,有不小的危害性,如果目前无法修复的话,个人认为有必要在 README 中给出警示The text was updated successfully, but these errors were encountered: