You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Switch语句渲染组件时TextInput按键输入异常问题

问题原因

核心问题是组件定义位置导致的实例重复创建:

  • Step1被定义在AddProductModal组件内部,每次父组件因state更新(比如输入字符触发setTitle)重渲染时,Step1会被重新定义为全新的组件类型。
  • React会判定这是完全不同的组件,随即卸载旧的Step1实例并挂载新实例,导致TextInput丢失焦点、输入中断,表现为每输入一个字符就停止响应。
  • 而直接调用Step1()时,本质是在render阶段执行函数返回JSX,并非作为组件实例渲染,不会触发卸载/重建流程,因此无异常。
解决方案

方案1:将Step1移到父组件外部定义

把Step1抽离为独立组件,避免每次父组件重渲染时组件类型被重置:

// 抽离Step1到AddProductModal外部
const Step1 = ({ title, setTitle }) => (
    <ScrollView>
        <View style={styles.InputContainer}>
            <Text style={{ fontFamily: 'Gilroy-SemiBold', fontSize: 18, marginTop: 30 }}>Title</Text>
            <TextInput 
                allowFontScaling={false} 
                value={title} 
                onChangeText={(value) => setTitle(value)} 
                style={styles.singleInput} 
            />
        </View>
    </ScrollView>
)

export default function AddProductModal({isVisible, toggleModal, page, setPage})  {
    const [title, setTitle] = useState('') 

    const getCurrentComponent = () => {
           switch (page) {
           case 1:
               return <Step1 title={title} setTitle={setTitle}/>;
           case 2:
               return <Step2/>;
           }
    ;}

    return (
         <View>
             {getCurrentComponent()}
         </View>
    )
}

方案2:用useMemo缓存组件渲染结果

通过useMemo缓存getCurrentComponent的返回值,仅当page变化时重新生成组件:

import { useMemo } from 'react';

export default function AddProductModal({isVisible, toggleModal, page, setPage})  {
    const [title, setTitle] = useState('') 

    const Step1 = () => (
        <ScrollView>
            <View style={styles.InputContainer}>
                <Text style={{ fontFamily: 'Gilroy-SemiBold', fontSize: 18, marginTop: 30 }}>Title</Text>
                <TextInput 
                    allowFontScaling={false} 
                    value={title} 
                    onChangeText={(value) => setTitle(value)} 
                    style={styles.singleInput} 
                />
            </View>
        </ScrollView>
    )

    const getCurrentComponent = useMemo(() => {
           switch (page) {
           case 1:
               return <Step1/>;
           case 2:
               return <Step2/>;
           }
    }, [page]); // 仅page变化时重新计算

    return (
         <View>
             {getCurrentComponent}
         </View>
    )
}

方案3:直接在render中使用条件渲染

跳过中间函数,直接在JSX中用条件判断渲染组件,逻辑更直观:

export default function AddProductModal({isVisible, toggleModal, page, setPage})  {
    const [title, setTitle] = useState('') 

    const Step1 = () => (
        <ScrollView>
            <View style={styles.InputContainer}>
                <Text style={{ fontFamily: 'Gilroy-SemiBold', fontSize: 18, marginTop: 30 }}>Title</Text>
                <TextInput 
                    allowFontScaling={false} 
                    value={title} 
                    onChangeText={(value) => setTitle(value)} 
                    style={styles.singleInput} 
                />
            </View>
        </ScrollView>
    )

    return (
         <View>
             {page === 1 && <Step1/>}
             {page === 2 && <Step2/>}
         </View>
    )
}

内容的提问来源于stack exchange,提问作者CodingJunkie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:00:18