React стирает значение поля ввода

#javascript #reactjs

#javascript #reactjs

Вопрос:

Полный пример на CodeSandbox

(Css немного искажен)

Запись чего-либо в поле ввода или текстовое поле, а затем нажатие на выбор стирает поле ввода и текстовое поле, я не уверен, почему —

Кажется, это потому, что я передаю элементы jsx элементу HoverWrapper.

Когда я только что вставил элемент, он вел себя так, как ожидалось. WrapInHover Я неправильно передаю элементы?

Добавление ключа к переданным элементам, похоже, не решило проблему …

 const Form = () => {
    const selectInit = {
        open: false,
        initial: true,
        selected: 'please select',
    };
    const selectReducer = (state, action) => {
        switch (action.type) {
            case 'toggle': {
                return { ...state, open: !state.open };
            }
            case 'select': {
                return { ...state, selected: action.selected, open: !state.open, initial: false };
            }
        }
    };
    const [selectState, selectDispatch] = useReducer(selectReducer, selectInit);
    const selectHelp = selected => selectDispatch({ type: 'select', selected });

    const OptionComp = ({ txt, value, onClick }) => (
        <Option onClick={onClick} state={selectState} value={value}>
            {selectState.open amp;amp; selectState.selected === value ? null : <HoverBorder />}
            {txt}
        </Option>
    );

    const WrapInHover = ({ elements }) => {
        const [hover, setHover] = useState(false);
        return (
            <div
                css={css`
                    position: relative;
                `}
                onMouseEnter={() => {
                    setHover(true);
                }}
                onMouseLeave={() => {
                    setHover(false);
                }}>
                {elements}
                <HoverBorder hover={hover} />
            </div>
        );
    };

    return (
        <FormEl>
            <WrapInHover elements={<Input key='ContactEmailInput' type='email' required />} />
            <Label htmlFor='subject' onClick={() => selectDispatch({ type: 'toggle' })}>
                Subject
            </Label>
            <Select>
                <OptionComp
                    onClick={() => selectHelp('art')}
                    txt='I want you to paint something !'
                    value='art'
                />
                {selectState.initial amp;amp; !selectState.open ? (
                    <OptionComp
                        txt='Please Select An Option'
                        value='please select'
                        onClick={() => selectDispatch({ type: 'toggle' })}
                    />
                ) : null}
            </Select>
        </FormEl>
    );
};
  

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

1. Я не вижу, чтобы состояние ввода где-либо сохранялось, так возможно ли, что при обновлении состояния оно перерисовывает входные данные и очищает значение?

Ответ №1:

Сохраняйте значение ввода и сообщения внутри состояния. Также ввод потеряет фокус, если ваш WrapInHover находится внутри основной функции

 
export default function App() {
  const Form = () => {
    const [formState, setFormState] = useState({ email: "", message: "" });
    ...
    const handleFormDataChange = (e, type) => {
      const {target: { value }} = e;
      setFormState((prevState) => ({ ...prevState, [type]: value }));
    };

    return (
      <FormEl>
        <FormTitle>Contact me</FormTitle>
        <Label htmlFor="email">Email</Label>
        <WrapInHover
          elements={
            <Input
              key="ContactEmailInput"
              type="email"
              value={formState.email}
              onChange={(e) => handleFormDataChange(e, "email")}
              required
            />
          }
        />
        ...
        <Label htmlFor="message">Message</Label>
        <WrapInHover
          elements={
            <TextArea
              key="ContactMessageTextArea"
              name="message"
              value={formState.message}
              onChange={(e) => handleFormDataChange(e, "message")}
            />
          }
        />
  

Пример CSB — я удалю через 24 часа.

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

1. «Также ввод будет терять ~~ фокус ~~ [состояние], если ваш обертывание находится внутри основной функции» <= Это была проблема! Почему компонент теряет состояние, когда он объявлен внутри другого компонента?