基于状态替换组件时的问题

Problem when a component is replaced based on a state

我是 React/Preact 的初学者,我遇到了一个我不明白的问题。 我有无线电输入来选择一个组件(FormInput)根据状态显示:

{
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,然后我显示 url,然后切换回 keyword。 HTML 的渲染是正确的,但是当我切换回 keyword 输入时,此输入的道具是 url 输入的道具。

但是,如果我通过添加 <></> 来更改 html 渲染,我就没有问题:

{
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>
}

请问我做错了什么? 谢谢。

编辑:FormInput 代码:

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>
    )
}

当你切换 FormInput 组件时,React 会尝试重新使用旧的来提高性能,所以它会保留旧的 props,当你使用 <></> 包裹关键字 FormInput, react 知道兄弟组件是不同的,所以它不会重复使用你的旧组件,你可以尝试向 FormInput 组件添加不同的 key 属性,这样告诉 react它们不同:

{
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>
}

更多信息:https://reactjs.org/docs/lists-and-keys.html#gatsby-focus-wrapper