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

时间:2019-04-13 01:24:55

标签: reactjs react-hooks

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

我确实知道,无需useImperativeHandle即可完成此操作,但我认为这里有一些优点。

我不知道的...

  1. 我是否“发现了显而易见的东西”,这真的没有用吗? ...或
  2. 这是不好的形式还是反模式?

我的代码正在运行-但我正在寻找有关最佳做法的信息。另外,由于目前关于useImperativeHandle的信息匮乏,因此超出输入ref的示例可能对其他人有用。

如果您想使用它,我在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. “酒吧”使用useImperativeHandle提供“呼入”功能,以防酒吧在做重要事情时可以否决其卸货。

正如我指出的那样,这很完美。在React中,数据和道具沿着树向下流动,而回调则向上流动。这为您提供了一种在特定情况下调用树的方法。建议吗?

1 个答案:

答案 0 :(得分:1)

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

惯用选项是:

因此,如果没有更简单的方法适合我的业务逻辑,那么我将执行以下操作以避免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})
}