用了context,ref还怎么用呢

背景

父组件A和子组件B都需要各自使用context来管理自己的状态,我平时都是这么用的
Context.tsx文件

import { makeContext } from '@ali/cs-react-context-utils';

function useLayoutContext() {
  const [state, setState] = React.useState();

  return {
    state
  };
}

const [LayoutContext, LayoutContextProvider] = makeContext<LayoutContextType>(useLayoutContext);
export { LayoutContext as default, LayoutContextProvider };

context提供者index.tsx文件

import React, { useContext } from 'react';

import { withContextProvider } from '@ali/cs-react-context-utils';
import LayoutContext, { LayoutContextProvider } from './LayoutContext';

function LayoutPage() {
  const contextValue = useContext(LayoutContext);
  return (
    <div>
    	这里是Context提供者
    </div>
  );
}

export default withContextProvider(LayoutContextProvider)(LayoutPage);

问题

然而这种方式有一个问题,就是当我想要在它的父组件使用ref来用这个实例组件的一些state和function的时候,会发现拿不到,打印ref.current结果为undefined,ref我是这么用的

子组件

import React, { forwardRef, useContext, useImperativeHandle } from 'react';

const LayoutPage = forwardRef((_, ref) => {

  const {state} = useContext(LayoutContext);
  // 通过useImperativeHandle将组件的state和functions暴露给父组件
   useImperativeHandle(ref, () => ({
    state,
  }));

  return <div>xxx</PageContainerDiv>;
});

export default withContextProvider(LayoutContextProvider)(LayoutPage);

父组件

import React, { useRef } from 'react';

const Parent = () => {
	const layoutRef = useRef();
	console.log(layoutRef?.current);
	return <LayoutPage ref={layoutRef} />
};

export default Parent;

查了资料发现,出现该问题的原因就是withContextProvider是一个高阶组件(HOC),它包裹了LayoutPage组件,导致ref指向HOC的实例而非原始组件,所以尽量避免这种写法

解决方案

就是使用react自己的createContext
Context.tsx文件


const LayoutContext = createContext(null);
const LayoutContextProvider = ListContext.Provider;

function useLayoutContext() {
  const [state, setState] = React.useState();

  return {
    state
  };
}

export { LayoutContext, LayoutContextProvider };

context提供者index.tsx文件

import React, { useContext } from 'react';
import { LayoutContextProvider, useLayoutContext } from './ListContext';

function LayoutPage() {
  const value = useListContext();
  return (
    <ListContextProvider value={value}>
    	xxx
    </ListContextProvider>
  );
}

export default LayoutPage;

这样再打印ref.current就没问题了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值