Как показать / скрыть счетчики, снэк-бары или другие переходные компоненты с помощью компонентов React Function - PullRequest
0 голосов
/ 08 марта 2019

Лучше ли визуализировать счетчики, закусочные и т. Д. В отдельных элементах DOM, а не добавлять их в основное дерево компонентов приложения?В компонентах класса React было действительно легко получить ссылку на методы компонентов класса, чтобы показать / скрыть счетчик.С новыми функциональными компонентами React Hooks это уже не так просто.Если я помещу счетчик в главное дерево компонентов, могу ли я использовать новый хук "useContext", чтобы показать / скрыть счетчик?

Ниже представлен глобальный счетчик React Hooks с использованием Material-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.

Ответы [ 3 ]

1 голос
/ 08 марта 2019

В компонентах класса React было действительно легко получить ссылку на методы компонентов класса, чтобы показать / скрыть счетчик

Вы можете продолжать использовать компоненты класса.Они никуда не денутся ?

Не очень хороший способ

На мой взгляд, на самом деле плохая практика - использовать методы класса, чтобы показывать и прятать счетчик.Предполагая, что ваш API выглядит как

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

И вы используете

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

Лучший способ

<Spinner shown={state.shown}/>

Теперь вы можете изменить state.shown вместо сохраненияref и используя show / hide.

0 голосов
/ 20 марта 2019

Хотя я думаю, что ответ Басарата - это современный способ решения этой проблемы, приведенный ниже код - это то, как я это сделал.Таким образом, мне нужна только одна строка кода для построения счетчика и только одна строка кода, чтобы показать / скрыть его.

   <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.
0 голосов
/ 16 марта 2019

Проблема похожа на на этот , и решение для блесны будет таким же, как и для модальных окон.Ловушки 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>
...