I'm a beginner to React/Preact and I'm facing to a problem that I don't understand. I have radio inputs to choose a component (FormInput) to display according to a state:
{
this.state.radio === true ?
<FormInput id="keyword" name="keyword" required={true}>Keyword</FormInput> :
<FormInput id="url" name="url" required={true} placeholder="https://" pattern={'https://.*'} >URL</FormInput>
}
keyword
is displayed first, then I display url
and a switch back to keyword
. The render of the HTML is correct but when I switch back to the keyword
input, the props of this input is the props of the url
input.
But if I change the html rendering by adding <></>
for example, I don't have the problem:
{
this.state.radio === true ?
<><FormInput id="keyword" name="keyword" required={true}>Keyword</FormInput></> :
<FormInput id="url" name="url" required={true} placeholder="https://" pattern={'https://.*'} >URL</FormInput>
}
What am I doing wrong please ? Thank you.
Edit: FormInput code:
export function FormInput(props: InputProps) {
const {
id,
name,
value = '',
required = false,
disabled = false,
readonly = false,
type = 'text',
autocomplete = 'off',
pattern,
children,
placeholder = children,
title = '',
setRef,
handleValueChange = () => {}
} = props;
let {classInputName = '', classGroupName = ''} = props;
classInputName = classNames('form-control', classInputName)
classGroupName = classNames('form-group', classGroupName)
let inputDom = setRef;
if(!setRef){
inputDom = useRef(null) as Ref<HTMLInputElement>;
}
const onInput = useCallback((e: any) => {
handleValueChange(name, e.target.value,);
}, []);
return (
<div class={classGroupName}>
{children ?
<label for={id}>{children}{required ? <span title="Required" rel="tooltip" class="required badge badge-empty rounded-circle ml-2"/> : ''}</label>
: <></>}
<input
ref={inputDom}
{...{id, name, type, required, disabled, readonly, pattern, onInput, placeholder, value, autocomplete, title}}
class={classInputName}
/>
</div>
)
}
CodePudding user response:
when you switch FormInput component, React will try to re-use the old one for performance, so it will keep the old one's props, when you use <></> to warp the keyword FormInput, react knows the sibling components are different, so it won't re-use your old component, you can try to add different key
prop to FormInput
component, like this to tell react they are different:
{
this.state.radio === true ?
<FormInput key="keyword" id="keyword" name="keyword" required={true}>Keyword</FormInput> :
<FormInput key="url" id="url" name="url" required={true} placeholder="https://" pattern={'https://.*'} >URL</FormInput>
}
further imformation: https://reactjs.org/docs/lists-and-keys.html#gatsby-focus-wrapper