如何在 React 中编写 useComponent 自定义钩子?
Posted
技术标签:
【中文标题】如何在 React 中编写 useComponent 自定义钩子?【英文标题】:How to write a useComponent custom hook in React? 【发布时间】:2021-12-30 20:52:04 【问题描述】:我想创建一个自定义钩子useComponent
,它返回一个JSX.Element
,它将在其他地方呈现。
我试过这个:
import useState from 'react';
const useComponent = () =>
const [value, setValue] = useState('');
const c = () =>
return <>
<p>Component</p>
<input value=value onChane=(e) => setValue(e.target.value) />
</>
return
c,
value,
export default function App()
const c: C = useComponent();
return (
<div className="App">
<C />
</div>
);
但它不起作用。一旦我尝试输入输入,什么都没有发生。
我怎样才能做到这一点?
我知道做这样的事情可能是一种不好的做法,但我想要这样做的原因是能够打开一个全局对话框并将c
组件作为children
传递给<Dialog />
组件所以我既可以在对话框主体内渲染c
,也可以访问[value, setValue]
状态。所以我的用例是这样的:
[编辑]
我还用对话框添加了整个逻辑:
import createContext, useContext, useState from "react";
const Test = ( value, setValue ) =>
return (
<>
<p>Component</p>
<input value=value onChange=(e) => setValue(e.target.value) />
</>
);
;
const useComponent = () =>
const [value, setValue] = useState("");
return
element: <Test value=value setValue=setValue />,
value
;
;
const DialogCTX = createContext();
export function DialogProvider(props)
const [component, setComponent] = useState(null);
const ctx =
component,
setComponent
;
return (
<DialogCTX.Provider value= ctx >
props.children
</DialogCTX.Provider>
);
export const useDialog = () =>
const
component,
setComponent,
= useContext(DialogCTX);
return
component,
setComponent,
;
const Dialog = () =>
const component = useDialog();
return <div>
<p>Dialog</p>
component
</div>
const Setter = () =>
const element, value = useComponent();
const setComponent = useDialog();
return <div>
<p>Setter component</p>
<p>value</p>
<button onClick=() => setComponent(element)>Set</button>
</div>
export default function App()
return <div className="App">
<DialogProvider>
<Setter />
<Dialog />
</DialogProvider>
</div>;
【问题讨论】:
【参考方案1】:正如你所说,你想返回一个JSX.Element
,但实际上每次你的钩子运行时你都会返回一个新组件(一个新函数)。因此,如果您实际上在钩子之外声明您的组件并返回渲染的组件,您就可以实现您的目标。这是一个工作示例:
import useState from "react";
const Test = ( value, setValue ) =>
return (
<>
<p>Component</p>
<input value=value onChange=(e) => setValue(e.target.value) />
</>
);
;
const useComponent = () =>
const [value, setValue] = useState("");
return
element: <Test value=value setValue=setValue />,
value
;
;
export default function App()
const element = useComponent();
return <div className="App">element</div>;
【讨论】:
请看看我的编辑。您的解决方案似乎仅在子项在创建状态的组件内呈现时才有效。 @entropyfeverone 确实,否则您需要为您的输入创建某种全局状态(可能使用上下文),但我不确定它是否像您想要的那样可扩展。检查这个code sandbox 你能在 Skroutz 推荐我吗? :p 哈哈,我们其实没有推荐系统,但是目前有很多空缺,去吧!以上是关于如何在 React 中编写 useComponent 自定义钩子?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 axios 拦截器中编写重定向而不在 React JS 中重新加载
如何编写依赖于 React 中 useState 钩子的条件渲染组件的测试?
如何使用 React、Jest 和 React-testing-library 为带有令牌的 api 调用编写单元测试?