Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(control): Introduce control hooks #108

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

599316527
Copy link
Member

@599316527 599316527 commented Nov 12, 2021

目标

通过hooks简化弹窗类组件的调用。

现状

实现弹窗交互时我们通常写出这样的代码。当组件需求越来越复杂,或者一个页面中出现多个弹窗时,这样的写法使得组件内 state 满天飞,可维护性急剧下降。同时,打开弹窗操作所引起的 state 更新会导致整个组件刷新,照成性能问题。

function Demo() {
    const [editId, setEditId] = useState();
    const [editField, setEditField] = useState();
    const EditorDialog = fieldToEditorMap[editField];

    const openEditor = useCallback((id, field) => {
        setEditId(id)
        setEditField(field)
    }, [setEditId, setEditField]);

    return <>
        <MassiveTable>
            ...
            <SomeButton onClick={() => openEditor(xxxId, field)} />
            ...
        </MassiveTable>
        {EditorDialog && <EditorDialog id={editId} onClose={() => setEditField(undefined)} />}
    </>;
}

解决

把弹窗相关逻辑独立成组件提升可维护性。并且通过 useControluseControlSource hook 来关联两者,实现简单易用。

function Demo() {
    const [ControlledEditor, {open: openEditor}] = useControl(Editor);

    return <>
        <MassiveTable>
            <SomeButton onClick={() => openEditor(xxxId, field)} />
        </MassiveTable>
        <ControlledEditor />
    </>;
}

function Editor(props, ref) {
    const [[editId, editField], {close}] = useControlSource(ref, (setState) => ({
        open: (id, field) => setState([id, field]),
        close: () => setState([])
    }), []);
    const EditorDialog = fieldToEditorMap[editField];
    {EditorDialog && <EditorDialog id={editId} onClose={close} />}
}

这样无论是直接使用 open 还是把它通过 context 往下传递,调用它开关弹窗都不会导致其它地方的无意义刷新。

目前在业务代码里用起来还挺方便的,所以感觉可以放到 huse 里面。

更详细的例子可以看 demo 实现。

@599316527 599316527 changed the title Introduce control hooks (feat:control) Introduce control hooks Nov 12, 2021
@599316527 599316527 changed the title (feat:control) Introduce control hooks feat(control): Introduce control hooks Nov 12, 2021
@otakustay
Copy link
Member

我终于看懂了……核心是利用ref跨组件地传递一些命令式的功能,这个思路很棒

具体到类型的完备性和命名,我再仔细推敲一下

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants