Обновление компонента после изменения ссылки.current

#javascript #reactjs

#javascript #reactjs

Вопрос:

Моя цель — отобразить следующий код, как только joinedRef.current он изменится на true. Из документации React я узнал, что React не сообщает, когда .current изменяется, что теперь ставит меня перед проблемой, что моя кнопка не отображается. В документации, на которую они ссылаются здесь .

Однако я не уверен, как изменить мой код, чтобы заставить это работать. Моя лучшая идея — вместо этого добавить useState эффект сверху. Но как решить, useCallback какой подход кажется лучшим?

Извлечение компонента

 {joinedRef.current amp;amp; (
  <>
    {console.log(joinedRef.current)}
    <Portal container={actionToolbarAnchor.current}>
      <ActionToolbarButton
        title="Video Call Settings"
        onClick={handlePortalClick}
      >
        <Icon icon={faCog} />
      </ActionToolbarButton>
    </Portal>
  </>
)}
  

Компонент

 const IntegrationDaily = ({ eventSlug, elementId, participants }) => {
  const classes = useStyles();
  const iframeRef = useRef();
  const dailyRef = useRef();
  const joinedRef = useRef();
  const joiningRef = useRef();
  const actionToolbarAnchor = useActionToolbar();

  useEffect(() => {
    dailyRef.current = DailyIframe.wrap(iframeRef.current, {
      // showLeaveButton: true,
    });

    dailyRef.current.on(eventTypes.LEFT_MEETING, () => {
      joinedRef.current = false;
    });

    dailyRef.current.on(eventTypes.JOINING_MEETING, () => {
      joiningRef.current = true;
    });

    dailyRef.current.on(eventTypes.JOINED_MEETING, () => {
      joiningRef.current = false;
      joinedRef.current = true;
    });

    return () => {
      joinedRef.current amp;amp; dailyRef.current.destroy();
    };
  }, []);

  const handlePortalClick = () => {
    console.log(dailyRef.current);
  };

  return (
    <>
      <iframe
        ref={iframeRef}
        className={classes.root}
        title="Video Meeting"
        frameBorder="0"
        allow="camera; microphone; display-capture; fullscreen"
      />
      {joinedRef.current amp;amp; (
        <>
          {console.log(joinedRef.current)}
          <Portal container={actionToolbarAnchor.current}>
            <ActionToolbarButton
              title="Video Call Settings"
              onClick={handlePortalClick}
            >
              <Icon icon={faCog} />
            </ActionToolbarButton>
          </Portal>
        </>
      )}
    </>
  );
};

export default IntegrationDaily;
  

Комментарии:

1. В чем проблема использования setState ? Я не уверен, насколько ссылки полезны в вашем случае. Ссылки требуются, когда вы играете с изменениями dom, и вы не хотите отображать свой компонент. В вашем случае это выглядит как изменение данных, так почему бы не использовать состояния?

Ответ №1:

Не имеет отношения к приведенному вами коду — ниже приводится объяснение относительно ссылки из react-docs;

useCallback используется, чтобы избежать переопределения функции при каждом рендеринге, поскольку список зависимостей пуст;

measuredRef это callback тип ref-подписи, что означает, что атрибут ref в react-js также выполняет функцию с подписью — node => {//...do smthing with node} ;

Попытка использовать то же самое в приведенном выше коде может привести к чему-то вроде этого —

 //...
const [joiningRef, setJoiningRef] = useState(false);
const [joinedRef, setJoinedRef] = useState(false);
const dailyRef = useRef();

useEffect(()=>{
     return ()=>{
          joinedRef amp;amp; dailyRef.current amp;amp; dailyRef.current.destroy()
     }
  }, [])

const iframeRef = useCallback((frame) => {
    if(!frame){
        if(dailyRef.current){
            dailyRef.current = null;
        }
        return;
    }
    
    const dframe = DailyIframe.wrap(frame, {
      // showLeaveButton: true,
    });

    dframe.on(eventTypes.LEFT_MEETING, () => {
      setJoinedRef(false);
    });

    dframe.on(eventTypes.JOINING_MEETING, () => {
      setJoiningRef(true);
    });

    dframe.on(eventTypes.JOINED_MEETING, () => {
      setJoiningRef(false);
      setJoinedRef(true);
    });
    
    dailyRef.current = dframe;
  }, []);

 useEffect(()=>{
    // react when joinedRef changes;
 },[joinedRef])

// use `joinedRef` rather than `joinedRef.current` to conditionally show the Portal fragment
//...
  

Комментарии:

1. Спасибо за объяснение. Только одна вещь, о которой я был смущен, — это то, откуда frame она исходит. Это то, что я также должен определить, как const frame = useRef() указано выше? Я видел, что это то же самое в примере React doc, который я опубликовал. Однако мне также непонятно node , откуда это происходит.

2. @JoeyCoder — это предопределенная структура с react, т.Е.. в react-библиотеке — это может быть реализовано как — если ref function передается в компоненте, затем вызовите эту функцию с помощью подходящего html-dom; При разработке компонентов — эта функция доступна для нас, чтобы получить этот узел dom и что-то с ним сделать, передав функцию в ссылку; Ивам не нужно определять const frame = useRef()