Javascript useRef未定义

Javascript useRef未定义,javascript,reactjs,Javascript,Reactjs,我想从父功能组件调用子功能组件的方法。我已经创建了useRef,并通过道具将其放到子组件中。我已经用forwardRef包装了子组件。但我得到了一个未定义的ref。 而且,我没有办法将ref放在dom元素上(只放在函数组件上) 父组件: import Tree from '@c-tree' import React, { FunctionComponent, useEffect, useState, useContext, useRef, } from 'react';

我想从父功能组件调用子功能组件的方法。我已经创建了useRef,并通过道具将其放到子组件中。我已经用forwardRef包装了子组件。但我得到了一个未定义的ref。 而且,我没有办法将ref放在dom元素上(只放在函数组件上)

父组件:

import Tree from '@c-tree'   
import React, {
  FunctionComponent,
  useEffect,
  useState,
  useContext,
  useRef,
} from 'react';


const NavTree: FunctionComponent = () => {
  
  const refTree = useRef();

useEffect(() => {

    if (refTree !== undefined && refTree.current !== undefined) {
      // @ts-ignore
      console.log(refTree.current.handleCurrentSelected);
    }

    // eslint-disable-next-line
  }, [refTree]);

  const tree = () => {
    if (d?.items) {
      return (
        <Tree ref={refTree}>
          {d.items.map(s => (
            <Tree.Asset
              key={s.id}
              name={s.name}
              dataSelected={`${s.id}`}
              item={{
                name: s.name,
                tenantID: s.id,
                type: s?.tree?.name,
                children: [],
              }}
            />
          ))}
        </Tree>
      );
    }
  };

  return (
    <SideBar
      title={title}
    >
      <Box display="flex" flexDirection="column" height="100%">
        <StyledBox>{tree()}</StyledBox>
      </Box>
    **</SideBar>
  );
};
export default NavTree;
import React, { useImperativeHandle, useState, ForwardRefExoticComponent, forwardRef, PropsWithRef } from 'react';

import TreeContext from './treeContext';
import TreeGroup from './components/TreeGroup';
import TreeEntity from './components/TreeEntity';

interface TabsStatic {
  Group: typeof TreeGroup;
  Asset: typeof TreeEntity;
}

type TabsComponent = ForwardRefExoticComponent<PropsWithRef<ITreeProps>> & TabsStatic;

interface ITreeProps {
  data?: {
    type: string;
    name: string;
    tenantID: number;
    children?: Array<Object>;
  }[];
  ref?: any;
}

export const Tree = forwardRef(({
  data,
}: ITreeProps, ref) => {
  const [contextValues, setContextValues] = useState({
    selected: null,
    opened: {},
  });

  useImperativeHandle(ref, () => (
    {
    handleCurrentSelected: (selectedName: string) => {
      setContextValues({
      ...contextValues,
      selected: selectedName,
      opened: {
        ...contextValues.opened,
        [selectedName]: !contextValues.opened[selectedName] || false,
      },
    });
  }}
  ));


  return (
    <TreeContext.Provider value={contextValues}>
        {
          React.Children.map(children, child => {
            return React.cloneElement(child, childrenProps);
          })
        }
    </TreeContext.Provider>
  );
}) as TabsComponent;

Tree.Group = TreeGroup;
Tree.Asset = TreeEntity;

export default Tree;
从“@c-Tree”导入树
进口反应{
功能组件,
使用效果,
useState,
使用上下文,
useRef,
}从"反应",;
常量导航树:FunctionComponent=()=>{
const refTree=useRef();
useffect(()=>{
if(refTree!==未定义&&refTree.current!==未定义){
//@ts忽略
console.log(refTree.current.handleCurrentSelected);
}
//eslint禁用下一行
},[refTree]);
常数树=()=>{
如果(d?项){
返回(
{d.items.map(s=>(
))}
);
}
};
返回(
{tree()}
**
);
};
导出默认导航树;
子组件:

import Tree from '@c-tree'   
import React, {
  FunctionComponent,
  useEffect,
  useState,
  useContext,
  useRef,
} from 'react';


const NavTree: FunctionComponent = () => {
  
  const refTree = useRef();

useEffect(() => {

    if (refTree !== undefined && refTree.current !== undefined) {
      // @ts-ignore
      console.log(refTree.current.handleCurrentSelected);
    }

    // eslint-disable-next-line
  }, [refTree]);

  const tree = () => {
    if (d?.items) {
      return (
        <Tree ref={refTree}>
          {d.items.map(s => (
            <Tree.Asset
              key={s.id}
              name={s.name}
              dataSelected={`${s.id}`}
              item={{
                name: s.name,
                tenantID: s.id,
                type: s?.tree?.name,
                children: [],
              }}
            />
          ))}
        </Tree>
      );
    }
  };

  return (
    <SideBar
      title={title}
    >
      <Box display="flex" flexDirection="column" height="100%">
        <StyledBox>{tree()}</StyledBox>
      </Box>
    **</SideBar>
  );
};
export default NavTree;
import React, { useImperativeHandle, useState, ForwardRefExoticComponent, forwardRef, PropsWithRef } from 'react';

import TreeContext from './treeContext';
import TreeGroup from './components/TreeGroup';
import TreeEntity from './components/TreeEntity';

interface TabsStatic {
  Group: typeof TreeGroup;
  Asset: typeof TreeEntity;
}

type TabsComponent = ForwardRefExoticComponent<PropsWithRef<ITreeProps>> & TabsStatic;

interface ITreeProps {
  data?: {
    type: string;
    name: string;
    tenantID: number;
    children?: Array<Object>;
  }[];
  ref?: any;
}

export const Tree = forwardRef(({
  data,
}: ITreeProps, ref) => {
  const [contextValues, setContextValues] = useState({
    selected: null,
    opened: {},
  });

  useImperativeHandle(ref, () => (
    {
    handleCurrentSelected: (selectedName: string) => {
      setContextValues({
      ...contextValues,
      selected: selectedName,
      opened: {
        ...contextValues.opened,
        [selectedName]: !contextValues.opened[selectedName] || false,
      },
    });
  }}
  ));


  return (
    <TreeContext.Provider value={contextValues}>
        {
          React.Children.map(children, child => {
            return React.cloneElement(child, childrenProps);
          })
        }
    </TreeContext.Provider>
  );
}) as TabsComponent;

Tree.Group = TreeGroup;
Tree.Asset = TreeEntity;

export default Tree;
import React,{UseImperialiveHandle,useState,ForwardRefExoticComponent,forwardRef,PropsWithRef}从“React”导入;
从“/TreeContext”导入TreeContext;
从“/components/TreeGroup”导入TreeGroup;
从“./components/TreeEntity”导入TreeEntity;
接口选项卡静态{
组:树群类型;
资产:树的类型;
}
类型TabsComponent=ForwardRefExoticComponent&tabssstatic;
接口ITreeProps{
数据?:{
类型:字符串;
名称:字符串;
租户编号:;
子:数组;
}[];
参考?:任何;
}
导出常量树=forwardRef(({
数据,
}:ITreeProps,ref)=>{
常量[contextValues,setContextValues]=useState({
选中:空,
已打开:{},
});
使用命令式句柄(参考,()=>(
{
handleCurrentSelected:(selectedName:string)=>{
setContextValues({
…上下文值,
selected:selectedName,
打开:{
…contextValues.opened,
[selectedName]:!contextValues.打开[selectedName]| | false,
},
});
}}
));
返回(
{
React.Children.map(Children,child=>{
返回React.cloneElement(child,childrenProps);
})
}
);
})作为选项卡组件;
Tree.Group=TreeGroup;
Tree.Asset=TreeEntity;
导出默认树;
已更新


我可以在重新渲染后获得useRef.current值。如何获取useRef当前(而非以前)值?

import React,然后使用
React.useRef()
来使用此挂钩。很抱歉,我在这个问题中没有为父组件指定导入。已更新。请尝试从“@c-Tree”导入{Tree}
useffect(()=>{…}[refTree.current])
您当前的效果相当于
componentDidMount
我注意到在重新渲染后出现了useRef。但当我只加载一个页面时,我没有定义。