创建树时无法使用上下文 API



我正在尝试制作一棵树并使用上下文API,以便树的所有节点都可以调用父函数。

这是我的树的开始

<Filter>
    {dataSource.map((x, i) => {
        return <DataTree
            key={i}
            name={x.name}
            type={x.type}
            children={x.children}
        />
    })}
</Filter>

这是我的树节点

function DataTree(props) {
    const [isOpen, setIsOpen] = useState(false)
    return (
        <div className="mt-3">
            <div className="row">
                {props.children &&
                    <button className="btn-primary mr-2" onClick={() => setIsOpen(!isOpen)}>+</button>
                }
                <h5 onClick={() => props.setFilter(props.name, props.type)}>{props.name}</h5>
            </div>
            <h1>{JSON.stringify(props.filters)}</h1>
            <div className="pl-5">
                <Filter>
                    {isOpen && props.children && props.children.map((x, i) => {
                        return <DataTree
                            key={i}
                            name={x.name}
                            type={x.type}
                            children={x.children}
                        />
                    })}
                </Filter>
            </div>
        </div>
    )
}
export default withFilter(DataTree)

这是我的上下文 API 的 HOC

const FilterContex = React.createContext()
export function Filter(props) {
    const [filters, setFilters] = useState({})
    const addToFilter = (value, name) => {
        setFilters({ ...filters, [name]: value })
    }
    return (
        <FilterContex.Provider value={{ filters, setFilter: addToFilter }}>
            {props.children}
        </FilterContex.Provider>
    )
}
export function withFilter(Component) {
    return function FilterComponent(props) {
        return (
            <FilterContex.Consumer>
                {context => <Component {...props} {...context} />}
            </FilterContex.Consumer>
        )
    }
}

问题是在我的DataTree中,我正在渲染的DataTree不是具有withFilter的,因此只有树的第一个节点具有上下文 API。

如何自行渲染包含withFilterDataTree?另外,我不确定我是否使上下文API正常工作。

由于您使用的是钩子,因此最好将钩子作为模式而不是 HOC。因此,您的解决方案将包括使用useContext钩子来访问组件中的上下文

数据树

function DataTree(props) {
    const [isOpen, setIsOpen] = useState(false)
    const {filters, setFilter} = useContext(FilterContex);
    return (
        <div className="mt-3">
            <div className="row">
                {props.children &&
                    <button className="btn-primary mr-2" onClick={() => setIsOpen(!isOpen)}>+</button>
                }
                <h5 onClick={() => setFilter(props.name, props.type)}>{props.name}</h5>
            </div>
            <h1>{JSON.stringify(filters)}</h1>
            <div className="pl-5">
                <Filter>
                    {isOpen && props.children && props.children.map((x, i) => {
                        return <DataTree
                            key={i}
                            name={x.name}
                            type={x.type}
                            children={x.children}
                        />
                    })}
                </Filter>
            </div>
        </div>
    )
}
export default DataTree;

过滤器接口

export const FilterContex = React.createContext()
export function Filter(props) {
    const [filters, setFilters] = useState({})
    const addToFilter = (value, name) => {
        setFilters({ ...filters, [name]: value })
    }
    return (
        <FilterContex.Provider value={{ filters, setFilter: addToFilter }}>
            {props.children}
        </FilterContex.Provider>
    )
}

如果您想知道如何使用 HOC 实现相同的效果,则需要创建一个新的连接 DataTree 组件并将其用于嵌套渲染

function DataTree(props) {
    const [isOpen, setIsOpen] = useState(false)
    return (
        <div className="mt-3">
            <div className="row">
                {props.children &&
                    <button className="btn-primary mr-2" onClick={() => setIsOpen(!isOpen)}>+</button>
                }
                <h5 onClick={() => props.setFilter(props.name, props.type)}>{props.name}</h5>
            </div>
            <h1>{JSON.stringify(props.filters)}</h1>
            <div className="pl-5">
                <Filter>
                    {isOpen && props.children && props.children.map((x, i) => {
                        return <DataTreeWithFilter
                            key={i}
                            name={x.name}
                            type={x.type}
                            children={x.children}
                        />
                    })}
                </Filter>
            </div>
        </div>
    )
}
const DataTreeWithFilter = withFilter(DataTree);
export default DataTreeWithFilter;

相关内容

  • 没有找到相关文章

最新更新