首页 > 解决方案 > 将组件的部分指定为子组件

问题描述

我想将我的 React 组件放在 DOM 中,如下所示:

<Table>
    <FirstNameColumnHeader>First Name</FirstNameColumnHeader>
    <LastNameColumnHeader>Last Name</LastNameColumnHeader>
    ...
    <FirstNameRowContent>John</FirstNameRowContent>
    <LastNameRowContent>Doe</LastNameRowContent>
</Table>

Table像这样的东西在哪里:

<table>
    <thead>
        <tr>
            <th>{ CONTENT OF FirstNameColumnHeader }</th>
            <th>{ CONTENT OF LastNameColumnHeader }</th>
        </tr>
    </thead>

    <tbody>
        <tr>
            <td>{ CONTENT OF FirstNameRowContent }</td>
            <td>{ CONTENT OF LastNameRowContent }</td>
        </tr>
    </tbody>
</table>

所以它想有效地过滤Table特定类型组件的子组件,然后我想在组件内的特定位置呈现它们。有什么方法可以优雅地在 React 中做到这一点。到目前为止,我想出的最好的方法是在内部使用上下文提供程序Table并在子组件中使用它。

const DataTableContext = createContext({});
const useDataTableContext = () => useContext(DataTableContext);

const Table = ({ children }) => {
    const [firstNameColumnHeader, setFirstNameColumnHeader] = useState(null);

    return (
        <DataTableContext.Provider value={{ setFirstNameColumnHeader }}>
            {children}

            <table>
                <thead>
                    <tr>
                        <th>{ firstNameColumnHeader }</th>
            ...
        </DataTableContext.Provider>
    );
};

export const FirstNameColumnHeader = ({ children }) => {
    const { setFirstNameColumnHeader } = useDataTableContext();

    useEffect(() => {
        setFirstNameColumnHeader(<>{children}</>);
    }, []);

    return null;
};

它看起来很笨重,并且在状态中存储了一个 JSX 组件,我认为这是一种不好的做法。有没有更好的方法来实现我想要的?我觉得我试图以错误的方式解决这个问题。

标签: javascriptreactjsreact-hooks

解决方案


我认为有一些方法可以实现您的目标,但我鼓励您考虑为什么要这样做。如果目标是制作一个灵活、可重用的表格组件,那么有很多可用的,您仍然可以自己制作。您决定的这种格式将使这种组件结构难以维护,甚至更难于人类理解。HTML 中的表格结构已经非常简单——行和单元格。为什么不保持一致的结构并让您的自定义组件呈现 TD?

<Table>
  <Row>
    <FirstNameCell />
  </Row>
</Table>

推荐阅读