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