reactjs - 如何使用 React Function Components 显示/隐藏微调器、 snackbar 或其他 transient 组件

标签 reactjs typescript react-hooks

在单独的 DOM 元素中渲染微调器、 snackbar 等是否比将它们添加到主应用程序组件树更好?在 React 类组件中,很容易获得对类组件方法的引用来显示/隐藏微调器。有了新的 React Hooks 功能组件,一切就不再那么容易了。如果我将微调器放在主组件树中,我可以使用新的“useContext” Hook 来显示/隐藏微调器吗?

下面是一个使用 Material-UI 的 React Hooks 全局微调器,它可以工作,但非常 hacky。如何让它变得更优雅?

namespace Spinner {
   'use strict';

   export let show: any; // Show method ref.
   export let hide: any; // Hide method ref.

   export function Render() {
      const [visible, setVisible] = React.useState(false); //Set refresh method.

      function showIt() {
         setVisible(true); // Show spinner.
      }

      function hideIt() {
         setVisible(false); // Hide spinner.
      }

      const styles: any = createStyles({
         col1Container: { display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column' },
      });

      return (
         <div>
            {visible && <div style={styles.col1Container}>
               <CircularProgress key={Util.uid()}
                  color='secondary'
                  size={30}
                  thickness={3.6}
               />
            </div>}

            <SetSpinnerRefs showRef={showIt} hideRef={hideIt} />
         </div>
      ); // end return.
   } // end function.

   const mounted: boolean = true;

   interface iProps {
      showRef();
      hideRef();
   }

   function SetSpinnerRefs(props: iProps) {
      // ComponentDidMount.
      React.useEffect(() => {
         Spinner.show = props.showRef;
         Spinner.hide = props.hideRef;
      }, [mounted]);

      return (<span />);
   }
} // end module.

最佳答案

问题类似于this one ,旋转器的解决方案与模态窗口的解决方案相同。 React hooks 不会改变它的工作方式,但可以使其更加简洁。

组件层次结构中应该有单个微调器实例:

const SpinnerContext = React.createContext();

const SpinnerContainer = props => {
  const [visible, setVisible] = React.useState(false);

  const spinner = useMemo(() => ({
    show: () => setVisible(true),
    hide: () => setVisible(false),
  }), []);

  render() {
    return <>
      {visible && <Spinner />}
      <SpinnerContext.Provider value={spinner}>
        {props.children}
      </SpinnerContext.Provider>
    </>;
  }
}

它是通过上下文传递的:

const ComponentThatUsesSpinner = props => {
  const spinner = useContext(SpinnerContext);
  ...
  spinner.hide();
  ...
}

<SpinnerContainer>
  ...
  <ComponentThatUsesSpinner />
  ...
</SpinnerContainer>

关于reactjs - 如何使用 React Function Components 显示/隐藏微调器、 snackbar 或其他 transient 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55053212/

相关文章:

node.js - 为什么我在收到 409 响应时无法读取消息或状态代码?

javascript - Javascript 中的全局命名空间 : Migrating to TypeScript

angular - 如何使用 angular 和 typescript 从 .graphql 文件加载查询

reactjs - 如何通过 React Hook 使用 throttle 或去抖?

javascript - React-animarker 突出显示不随状态更改而更新

javascript - React Native ListView TouchableHighlight

javascript - React Native - 处理繁重的 JS 代码而不影响性能/渲染的最佳方法

javascript - 过滤 React js

javascript - 如何一键过滤json数组中的对象

reactjs - D3 条形图 + React Hooks - exit().remove() 不起作用