3 votes

inputFile.current.click() inside useEffect ne fonctionne pas dans safari

J'ai <input type="file" /> et veulent déclencher .click() sur cette entrée. Tout fonctionne bien dans chrome, firefox, edge mais le problème existe dans safari.

Quand je clique sur le bouton pour déclencher inputFile.current.click() - ça marche. Mais lorsque cela se produit à l'intérieur de useEffect/useLayoutEffect - cela ne fonctionne pas (j'ai essayé d'ajouter des délais d'attente et cela n'a pas aidé non plus).

Exemple de travail pour reproduire le problème : https://codesandbox.io/s/react-hooks-counter-demo-forked-49n2t?file=/src/index.js

Le moins de code possible pour présenter le problème

import React, { useCallback, useState, useEffect, useLayoutEffect, useRef } from 'react';
import { useRecoilState } from 'recoil';
import { requestedNewCanvasObjAtom } from '../SlidesState/slidesAtoms';

const Slide: React.FC = () => {
  const [trigger, setTrigger] = useState(false);
  const [requestedNewCanvasObj] = useRecoilState(requestedNewCanvasObjAtom);
  const inputFile = useRef(null);

  useLayoutEffect(() => {
    console.log('IT IS HERE WHEN EXPECTED BUT IT DOES NOT WORK TOO');
    inputFile.current.click();
  }, [requestedNewCanvasObj]);

  useLayoutEffect(() => {
    console.log('IT WORKS');
    inputFile.current.click();
  }, [trigger]);

  const triggerUpload = useCallback(() => {
    if (inputFile && inputFile.current) {
      console.log('IT WORKS');
      inputFile.current.click();
    }
  }, []);

  return (
    <>
      <button onClick={triggerUpload}>Click</button>
      <button onClick={() => setTrigger(true)}>Update state to trigger input click</button>
      <input type="file" id="file" ref={inputFile} />
    </>
  );
};

export default Slide;

CETTE QUESTION A ÉTÉ MISE À JOUR - le problème simplifié sans recul a été résolu par lissettdm mais il s'avère que mon problème est plus complexe

5voto

lissettdm Points 7005

L'événement "on click" est déclenché mais le finder ne s'affiche pas. Utilisez useLayoutEffect . Il se déclenche de manière synchrone après toutes les mutations du DOM :

  useLayoutEffect(()=> {
    if (inputRef && inputRef.current) {
      inputRef.current.click();
    }
  }, [count])

Dans d'autres navigateurs comme Chrome , useEffects y useLayoutEffect va travailler pour montrer le trouveur. Mais en Safari seulement le useLayoutEffect fonctionnera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X