-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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: