【发布时间】:2021-01-18 05:37:43
【问题描述】:
我有下一个错误:
错误:元素类型无效:应为字符串(对于内置 组件)或类/函数(用于复合组件),但得到: 不明确的。您可能忘记从文件中导出组件 它是在中定义的,或者您可能混淆了默认导入和命名导入。
我想在父组件中调用子函数。我尝试使用 useRef、forwardRef 和 useImperativeHandle
父组件:
import Tree from '@c-tree'
const NavTree: FunctionComponent = () => {
const refTree = useRef();
const tree = () => {
if (d?.items && status === 'idle') {
return (
<Tree onNodeClickCallback={onClick} 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;
子组件:
interface TreeStatic {
Group: typeof TreeGroup;
Asset: typeof TreeNode;
}
type TreeComponent = ForwardRefExoticComponent<PropsWithRef<ITreeProps>> & TreeStatic;
interface ITreeProps {
data?: {
type: string;
name: string;
tenantID: number;
children?: Array<Object>;
}[];
ref: any;
}
const Tree = ({
data,
ref
}: ITreeProps) => {
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>
);
};
Tree.Group = TreeGroup;
Tree.Asset = TreeNode;
export default forwardRef(Tree) as TreeComponent;
【问题讨论】:
-
你能告诉我们你将
Tree导入父组件文件的那一行吗? -
import Tree from '@c-tree' 是从 npm 包中导入的
-
所以子组件在npm包中?这是其他人编写的公共包并且您正在导入,还是您编写和发布的代码?谷歌搜索没有向我显示具有该名称的 npm 包的任何结果,尽管您可能正在使用私有 npm 存储库。
-
我问这些问题的原因是该错误几乎肯定与您的导入有关,而不是与 forwardref/useref/useImparativeHandle。
-
我用的是私有包。
标签: reactjs typescript