输入模态后反应输入丢失状态

时间:2021-07-22 07:44:50

标签: javascript reactjs react-hooks

我有一个模式,用户需要填写他的电子邮件地址。问题是输入字段在每次输入字母后都会丢失状态。

父组件:

const { show: openExampleMailingModal, ExampleMailingModal } = useExampleMailingHook(mailable);

<ExampleMailingModal />

示例MailingModal:

import React, { useState } from 'react';
import Modal from '@/crm/Shared/Modals/Modal';
import TextInput from '@/crm/Shared/TextInput';

export const useExampleMailingHook = (mailable) => {
    const [isVisible, setIsVisible] = useState(false);
    const [email, setEmail] = useState('');

    const show = () => setIsVisible(true);
    const hide = () => setIsVisible(false);

    const ExampleMailingModal = () => (
        <>
            {isVisible && (
                <Modal close={hide}>
                    <>
                        <TextInput
                            key="test123"
                            name="email"
                            placeholder="Email"
                            value={email}
                            onChange={(e) => setEmail(e.target.value)}
                        />
                    </>
                </Modal>
            )}
        </>
    );

    return {
        show,
        hide,
        ExampleMailingModal,
    };
};

文本输入:

import React from 'react';

export default ({ label, name, className, type = 'text', errors = [], ...props }) => {
    return (
        <div className={className}>
            {label && (
                <label htmlFor={name} className="block text-sm font-medium text-gray-700">
                    {label}
                </label>
            )}
            <input
                id={name}
                name={name}
                type={type}
                {...props}
                className={`mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm ${
                    errors.length ? 'border-red-500' : ''
                }`}
            />
            {errors && <div className="text-red-500 text-sm mt-1">{errors}</div>}
        </div>
    );
};

我在其他几个工作的地方使用输入字段。但在我的模式中它没有。我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

问题

您在每个渲染周期都声明了一个新的 ExampleMailingModal,因此旧的被卸载并安装了一个新的实例。这就是每次重新渲染后焦点都会丢失的原因。

解决方案

ExampleMailingModal 组件移出钩子,这样它就不会被重新声明并返回 JSX。

const ExampleMailingModal = ({ isVisible, hide, ...inputProps }) =>
  isVisible ? (
    <Modal close={hide}>
      <TextInput
        key="test123"
        name="email"
        placeholder="Email"
        {...inputProps}
      />
    </Modal>
  ) : null;

const useExampleMailingHook = (mailable) => {
  const [isVisible, setIsVisible] = useState(false);
  const [email, setEmail] = useState("");

  const show = () => setIsVisible(true);
  const hide = () => setIsVisible(false);

  return {
    show,
    hide,
    ExampleMailingModal: (
      <ExampleMailingModal
        isVisible={isVisible}
        hide={hide}
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
    )
  };
};

用法:

const { show, hide, ExampleMailingModal } = useExampleMailingHook();

...

{ExampleMailingModal}

Edit react-input-losing-state-after-typing-in-modal