此钩子只能在<Composer>react

问题描述 投票:0回答:1

我正在尝试使用

Microsoft BotFramework-WebChat
中的 useScrollTo 挂钩。

但是我收到以下错误:-

This hook can only be used on a component that is a descendant of <Composer>

我在函数组件内调用它,该组件又在

下调用
ReactDOM.render(
  <React.StrictMode>
    <-- the function component -->
  <React.StrictMode>
)

提前致谢

reactjs react-hooks botframework
1个回答
0
投票

我们来看看

useScrollTo()
钩子的源码:

import { useCallback } from 'react';

import ScrollPosition from '../types/ScrollPosition';
import useWebChatUIContext from './internal/useWebChatUIContext';

export default function useScrollTo(): (
  position: ScrollPosition,
  scrollToOptions: { behavior?: 'auto' | 'smooth' }
) => void {
  const { scrollToCallbacksRef } = useWebChatUIContext();

  return useCallback(
    (...args) => scrollToCallbacksRef.current.forEach(callback => callback(...args)),
    [scrollToCallbacksRef]
  );
}

useWebChatUIContext()
钩:

import { useContext } from 'react';

import WebChatUIContext from './WebChatUIContext';

export default function useWebChatUIContext() {
  const context = useContext(WebChatUIContext);

  if (!context) {
    throw new Error('This hook can only be used on a component that is a descendant of <Composer>');
  }

  return context;
}

错误是从

useWebChatUIContext()
钩子抛出的,
useScrollTo()
钩子需要来自
scrollToCallbacksRef
WebChatUIContext
,所以你必须在React函数组件中使用
useScrollTo()
钩子,并且它必须是的后代组件
<Composer/>

<Composer/>
组件渲染
<ComposerCore/>
<ComposerCore/>
组件渲染
<WebChatUIContext.Provider/>

看看这个测试用例

const RunFunction = ({ fn }) => {
   fn();

   return false;
};

// ...
const renderWithFunction = fn =>
new Promise(resolve =>
  ReactDOM.render(
    <Composer directLine={directLine} scrollToEndButtonMiddleware={scrollToEndButtonMiddleware} store={store}>
      <BasicWebChat />
      <RunFunction fn={() => resolve(fn && fn())} key={Date.now() + ''} />
    </Composer>,
    document.getElementById('webchat')
  )
);

// ...
await renderWithFunction(() => useScrollTo()({ scrollTop: 300 }));

useScrollTo()
钩子在
RunFunction
组件中调用,它是
<Composer/>

的子组件
© www.soinside.com 2019 - 2024. All rights reserved.