这是 React useImperativeHandle 挂钩的正确用例吗?
Is this a correct use case for the React useImperativeHandle hook?
我正在学习 React 挂钩(我对 React 还很陌生),并且正在考虑 useImperativeHandle 的用例。我想到了一个非常有用的场景。
我知道这可以在没有 useImperativeHandle 的情况下完成,但我认为这里有一些优点。
我不知道的...
- 我 'discovered the obvious' 这不是真的有用吗? ... 或
- 这是错误的形式还是反模式?
我的代码可以正常工作 - 但我正在寻找有关最佳实践的意见。此外,由于目前缺乏关于 useImperativeHandle 的信息,这个超出输入引用范围的示例可能对其他人有用。
我在 Github 上发布了一个最小示例,如果你想玩的话:
https://github.com/ericsolberg/react-uih-hook
使用类似于以下的标记:
const App = props => {
return (
<Foo>
<Bar>This is Bar 0</Bar>
<Bar>This is Bar 1</Bar>
<Bar>This is Bar 2</Bar>
</Foo>
);
};
我完成的是:
- 允许父组件 'Foo' 为其子组件提供状态存储 - 因此 Foo 可以 mount/dismount 子组件同时允许它们恢复状态。
- 'Bar' 使用 useImperativeHandle 提供一个 'call-in' 因此 Bar 可以否决被卸载,以防它正在做一些重要的事情。
正如我所说,这非常有效。在 React 中,数据和 props 沿着树向下流动,而回调向上流动。这为您提供了一种在特定情况下向下调用树的方法。是否可取?
这是一个反模式:Inject props into the children
没有显式传递 props。
惯用选项是:
- 显式传递道具
- use context
- Lifting state up 能够做到以上2
- render props
因此,如果没有更简单的方法适合我的业务逻辑,我将执行类似以下操作以避免 Foo 和 Bar 之间不可见的紧耦合:
const App = () => (
<Foo>
{({selector, saveStateFactory}) => (<>
<Bar state={selector(0)} saveState={saveStateFactory(0)} />
<Bar state={selector(1)} saveState={saveStateFactory(1)} />
</>)}
</Foo>
)
const Foo = () => {
const [state, dispatch] = useReducer(...)
const selector = (id) => state[id]
const saveStateFactory = (id) => {
return (payload) => dispatch({type: id, payload})
}
// do something with whole state that cannot be done in App nor Bar
return children({selector, saveStateFactory})
}
我正在学习 React 挂钩(我对 React 还很陌生),并且正在考虑 useImperativeHandle 的用例。我想到了一个非常有用的场景。
我知道这可以在没有 useImperativeHandle 的情况下完成,但我认为这里有一些优点。
我不知道的...
- 我 'discovered the obvious' 这不是真的有用吗? ... 或
- 这是错误的形式还是反模式?
我的代码可以正常工作 - 但我正在寻找有关最佳实践的意见。此外,由于目前缺乏关于 useImperativeHandle 的信息,这个超出输入引用范围的示例可能对其他人有用。
我在 Github 上发布了一个最小示例,如果你想玩的话: https://github.com/ericsolberg/react-uih-hook
使用类似于以下的标记:
const App = props => {
return (
<Foo>
<Bar>This is Bar 0</Bar>
<Bar>This is Bar 1</Bar>
<Bar>This is Bar 2</Bar>
</Foo>
);
};
我完成的是:
- 允许父组件 'Foo' 为其子组件提供状态存储 - 因此 Foo 可以 mount/dismount 子组件同时允许它们恢复状态。
- 'Bar' 使用 useImperativeHandle 提供一个 'call-in' 因此 Bar 可以否决被卸载,以防它正在做一些重要的事情。
正如我所说,这非常有效。在 React 中,数据和 props 沿着树向下流动,而回调向上流动。这为您提供了一种在特定情况下向下调用树的方法。是否可取?
这是一个反模式:Inject props into the children
没有显式传递 props。
惯用选项是:
- 显式传递道具
- use context
- Lifting state up 能够做到以上2
- render props
因此,如果没有更简单的方法适合我的业务逻辑,我将执行类似以下操作以避免 Foo 和 Bar 之间不可见的紧耦合:
const App = () => (
<Foo>
{({selector, saveStateFactory}) => (<>
<Bar state={selector(0)} saveState={saveStateFactory(0)} />
<Bar state={selector(1)} saveState={saveStateFactory(1)} />
</>)}
</Foo>
)
const Foo = () => {
const [state, dispatch] = useReducer(...)
const selector = (id) => state[id]
const saveStateFactory = (id) => {
return (payload) => dispatch({type: id, payload})
}
// do something with whole state that cannot be done in App nor Bar
return children({selector, saveStateFactory})
}