javascript 使用React Hooks从子对象聚焦父对象

t1qtbnec  于 2023-04-04  发布在  Java
关注(0)|答案(3)|浏览(93)

我试图在弹出对话框后聚焦父输入框。我试图将父的引用传递给子,并从子焦点,但很难使其工作。
我很感激你的帮助。
代码沙盒:https://codesandbox.io/s/modal-components-react-custom-hooks-forked-iyumhx?file=/src/Modal.js
验证码:

const App = () => {
  const { isShowing, toggle, setIsShowing } = useModal();
  const [input, setInput] = useState("");
  const ref = useRef();

  useEffect(() => {
    if (input != "") setIsShowing(true);
  }, [input]);

  return (
    <div className="App">
      <input type="text" ref={ref} onChange={(e) => setInput(e.target.value)} />
      <Modal
        isShowing={isShowing}
        hide={toggle}
        forwardRef={ref}
        input={input}
      />
    </div>
  );
};

在Console.log ref中,我可以看到Ref已定义,但focus函数不起作用。

const Modal = ({ isShowing, hide, forwardRef, input }) => {
  useEffect(() => {
    console.log(forwardRef);
    forwardRef.current.focus();
  }, []);

  return (
    <>
      <M
        isOpen={isShowing}
        role="dialog"
        autoFocus={true}
        centered={true}
        size="lg"
        // query={query}
        scrollable={false}
      >
        From Parent {input}
      </M>
    </>
  );
};
kx1ctssn

kx1ctssn1#

将您的模态useEffect更改为

useEffect(() => {
  if (forwardRef.current) {
    forwardRef.current.focus();
  }
}, [forwardRef]);
kpbwa7wx

kpbwa7wx2#

将autofocus设置为false。这将防止modal从输入中窃取焦点。

cu6pst1q

cu6pst1q3#

问题是reactstrap库中的modal默认有autoFocus={true},你必须将其设置为false,你也不需要useRef的帮助。
App.jsx

import React, { useState } from "react";
import ReactDOM from "react-dom";
import Modal from "./Modal";
import "./styles.css";
import { useBoolean } from "./useBoolean";

const App = () => {
  const [isModalOpen, openModal, closeModal] = useBoolean();
  const [inputValue, setInputValue] = useState("");

  return (
    <div className="App">
      <input
        type="text"
        value={inputValue}
        onChange={(e) => {
          if (e.target.value !== "") openModal();
          else closeModal();

          setInputValue(e.target.value);
        }}
      />
      <Modal isOpen={isModalOpen} inputValue={inputValue} />
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Modal.jsx

import React from "react";
import { Modal as M } from "reactstrap";

const Modal = ({ isOpen, inputValue }) => {
  return (
    <M
      isOpen={isOpen}
      autoFocus={false} // THIS PART WAS THE ISSUE, THIS SHOULD BE FALSE!
      centered={true}
      size="lg"
      scrollable={false}
    >
      Input: {inputValue}
    </M>
  );
};

export default Modal;

useBoolean.js

import { useCallback, useState } from "react";

export const useBoolean = () => {
  const [value, setValue] = useState(false);
  const onToggleOn = useCallback(() => setValue(true), []);
  const onToggleOff = useCallback(() => setValue(false), []);

  return [value, onToggleOn, onToggleOff];
};

相关问题