【发布时间】: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>;
}
【问题讨论】:
标签: reactjs react-hooks react-context react-component