简体   繁体   English

useEffect 中的 inputFile.current.click() 在 safari 中不起作用

[英]inputFile.current.click() inside useEffect doesn't work in safari

I have <input type="file" /> and want to trigger .click() on that input.我有<input type="file" />并想在该输入上触发.click() Everything works fine in chrome, firefox, edge but problem exists in safari.在 chrome 中一切正常,firefox,边缘但在 safari 中存在问题。

When I click on button to trigger inputFile.current.click() - it works.当我点击按钮触发inputFile.current.click() - 它工作。 But when it happens inside useEffect/useLayoutEffect - it doesn't work (I've tried adding timeouts and it also didn't help).但是当它发生在 useEffect/useLayoutEffect 内部时 - 它不起作用(我尝试添加超时,但它也没有帮助)。

Working example to reproduce problem: https://codesandbox.io/s/react-hooks-counter-demo-forked-49n2t?file=/src/index.js重现问题的工作示例: https://codesandbox.io/s/react-hooks-counter-demo-forked-49n2t?file=/src/index.js

As less code as possible to present problem尽可能少的代码来呈现问题

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;

THIS QUESTION WAS UPDATED - simplified problem without recoil was solved by useLayoutEffect but turns out that my problem is more complex这个问题已更新 - useLayoutEffect 解决了没有后坐力的简化问题,但事实证明我的问题更复杂

The on click event is fired but the finder doesn't show up. on click 事件被触发,但查找器不显示。 Use useLayoutEffect .使用useLayoutEffect It fires synchronously after all DOM mutations:它在所有 DOM 突变后同步触发:

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

In other browsers like Chrome , useEffects and useLayoutEffect will work to show the finder.Chrome等其他浏览器中, useEffectsuseLayoutEffect将用于显示查找器。 But in Safari , only the useLayoutEffect will work.但是在Safari中,只有useLayoutEffect可以工作。

@Żywy Add id to input and add label with htmlFor attribute. @Żywy 将id添加到输入并添加labelhtmlFor属性。

Important : Input element must not be inside the label重要提示:输入元素不得位于label内部

Check this codepen: https://codesandbox.io/s/react-hooks-counter-demo-forked-7bnut7?file=/src/index.js (click on the red text)检查这个codepen: https://codesandbox.io/s/react-hooks-counter-demo-forked-7bnut7?file=/src/index.js (点击红色文字)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM