子组件获取祖先组件的数据,这个逻辑没有问题,props/context 往下传都行。子组件存在的前提肯定是所有祖先组件都挂载存在了。
但是祖先组件获取子组件的数据、兄弟组件之间获取数据,这个有一个问题是,你要获取数据的那个组件可能不存在。
而你现在这个问题,综合了获取兄弟组件、子组件数据的情况。
你提到了“按照以往非组件化的思路应该是直接获取到这个 grid 对象,在调用对应的 getValue 方法就可以了”,这个在 React 中对应的就是 ref ,ref 上暴露 getValue 方法就是你说的这个了。函数组件没有对象实例可以用 React 提供的 forwardRef 。但是你也得要考虑一个事情是,这个实例引用变量存放在哪里,怎么去获取。因为这个 ref 的持有人默认只有挂载这个子组件的那个父组件,你又得要想办法把这个 ref 传给祖先、兄弟。
所以,这个 ref 的最佳存放位置就是共同祖先上,然后通过 context 往下传。但既然到了共同祖先这一步,那么就不要存 ref 了嘛,直接存数据就好?这就是楼上提到的数据存在共同祖先上,然后下面用 context 来读写数据。
祖先上不管是存数据还是存 ref 都是有自己的实际场景的。如果要调用对应组件的 API ,就还是得存 ref 。
然后另一个方案,全局状态,这个实际上也是把数据存在祖先上,只不过是存在根祖先上,子孙组件通过封装过的 context 读写数据。
不管是用全局状态还是自己写 context ,本质上都是数据存在祖先上,你在读取的时候不需要关心目标组件是否已经挂载存在,没挂载存在的话,你读到的就是个默认值。
或者楼上也有提到全局的通知广播,但这个一旦滥用就不好控制了。React 18 里有个 API ,useSyncExternalStore ,实际上也可以实现跨组件的共享,因为本质上数据是脱离 React 存在的,一个 store 实例,一个组件更新,一个组件监听,相当于一个小型的受限的广播系统,会比全局的广播好一些。 |