这是 React useImperativeHandle 钩子的正确用例吗?



我正在学习 React 钩子(我对 React 相当陌生),并且正在考虑 useImperativeHandle 的用例。我想出了一个非常有用的方案。

我知道这可以在不使用ImperativeHandle的情况下完成,但我认为这里有一些优点。

我不知道的...

  1. 我是否"发现了显而易见的",但这并没有真正有用?或
  2. 这是不好的形式,还是反模式?

我的代码正在工作 - 但我正在寻找有关最佳实践的输入。此外,由于现在缺乏有关 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>
);
};

我所取得的成就是:

  1. 允许父组件"Foo"为其子组件提供状态存储 - 因此Foo可以挂载/卸载子组件,同时允许它们恢复状态。
  2. "Bar"使用useImperativeHandle来提供"呼入",以便Bar可以否决被卸载,以防它正在做重要的事情。

正如我所指出的,这非常有效。在 React 中,数据和 prop 沿着树向动,而回调则向上流动。这为你提供了一种在特定情况下调用树的方法。是否可取?

这是一个反模式:Inject props into the children没有显式传递道具。

惯用选项是:

  • 显式传递道具
  • 使用上下文
  • 提升状态才能做到以上2项
  • 渲染道具

因此,如果没有更简单的东西适合我的业务逻辑,我会做如下操作以避免 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})
}

相关内容

  • 没有找到相关文章

最新更新