如何显示/隐藏旋转器,Snackbars或其他具有React功能组件的瞬态组件



在单独的DOM元素中而不是将它们添加到主应用程序组件树中,渲染旋转器,snackbars等更好吗?在React类组件中,很容易获取对显示/隐藏旋转器的类组件方法的引用。使用新的React Hooks功能组件,它不再那么容易了。如果我将旋转器放在主组件树中,我可以使用新的" usecontext"钩显示/隐藏旋转器?

下面是一种使用材料-UI,但非常刺眼的材料-UI。如何使这更优雅?

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.

该问题与此问题相似,并且旋转器的解决方案与模态窗口的解决方案相同。React钩子不会改变其工作方式,但可以使其更简洁。

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

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>

在React类组件中,很容易获得对类别组件方法的参考来显示/隐藏旋转器

您可以继续使用类组件。他们不会去任何地方🌹

不是很好的方法

我认为,使用班级方法显示和隐藏旋转器实际上是糟糕的做法。假设您的API看起来像

<Spinner {ref=>this.something=ref}/>

您使用

this.something.show(); // or .hide

更好的方法

<Spinner shown={state.shown}/>

现在,您可以更改state.shown而不是存储REF并使用show/hide

,尽管我认为巴萨拉特的答案是解决此问题的现代方法,但以下代码是我最终这样做的方式。这样,我只需要一行代码即可构建旋转器,只需要一行代码来显示/隐藏。

   <Spinner.Render />  {/* Build spinner component */}
   Spinner.show();     //Show spinner.
namespace Spinner {
   'use strict';
   export let show: any; //Ref to showIt method.
   export let hide: any; //Ref to hideIt method.
   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 showRef: any = React.useRef(showIt);
      const hideRef: any = React.useRef(hideIt);
      //Component did mount.
      React.useEffect(() => {
         Spinner.show = showRef.current;
         Spinner.hide = hideRef.current;
      }, []);
      const styles: any = createStyles({
         row1Container: { display: 'flex', alignItems: 'center', justifyContent: 'center' },
      });
      return (
         <div>
            {visible && <div style={styles.row1Container}>
               <CircularProgress
                  color='secondary'
                  size={30}
                  thickness={3.6}
               />
            </div>}
         </div>
      ); //end return.
   } //end function.
} //end module.

相关内容

  • 没有找到相关文章

最新更新