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

React+Ionic项目中客户端条目重复问题求助

问题:CRUD操作中客户端条目重复

在基于React+Ionic+TypeScript的客户端CRUD项目中,新增或编辑客户端时会出现条目重复的情况。

相关代码

editClient.tsx

const { name, id } = useParams<{
    name: string;
    id: string;
}>();

const [client, setClient] = useState<any>({});/* this array will be called when we do a search*/

useEffect(() => {search();}, []);

const history = useHistory();

const search = () => {
    if(id !== 'new') {
        let result = searchClientById(id);
        setClient(result);
    }
}

const save = () => {
    saveClient(client);
    history.push('/page/clients')
}

return (
    <IonPage>
        <IonHeader>
            <IonToolbar>
                <IonButtons slot="start">
                    <IonMenuButton />
                </IonButtons>
                <IonTitle>{name}</IonTitle>
            </IonToolbar>
        </IonHeader>

        <IonContent fullscreen>
            <IonHeader collapse="condense">
                <IonToolbar>
                    <IonTitle size="large"></IonTitle>
                </IonToolbar>
            </IonHeader>
            <IonCard>
                <IonTitle>{id === 'new' ? 'Set New Client' : 'Edit Client'}</IonTitle>
                <IonRow>
                    <IonCol>
                        <IonItem>
                            <IonLabel position="stacked">Name</IonLabel>
                            <IonInput onIonChange={e => client.firstname = e.detail.value} value={client.firstname}></IonInput>
                        </IonItem>
                    </IonCol>

                    <IonCol>
                        <IonItem>
                            <IonLabel position="stacked">Surname</IonLabel>
                            <IonInput onIonChange={e => client.surname = e.detail.value} value={client.surname}></IonInput>
                        </IonItem>
                    </IonCol>
                </IonRow>
                <IonRow>
                    <IonCol>
                        <IonItem>
                            <IonLabel position="stacked">Email</IonLabel>
                            <IonInput onIonChange={e => client.email = e.detail.value} value={client.email}></IonInput>
                        </IonItem>
                    </IonCol>

                    <IonCol>
                        <IonItem>
                            <IonLabel position="stacked">Adress</IonLabel>
                            <IonInput onIonChange={e => client.address = e.detail.value} value={client.address}></IonInput>
                        </IonItem>
                    </IonCol>
                    <IonCol>
                        <IonItem>
                            <IonLabel position="stacked">Phone</IonLabel>
                            <IonInput onIonChange={e => client.phone = e.detail.value} value={client.phone}></IonInput>
                        </IonItem>
                    </IonCol>
                </IonRow>
                <IonItem>
                    <IonButton onClick={save} color="primary" fill='solid' slot='end' size='default'>
                        <IonIcon icon={checkmark} />
                        Save Changes
                    </IonButton>
                </IonItem>
            </IonCard>
        </IonContent>
    </IonPage>
);

clientApi.tsx中的saveClient函数

export function saveClient(client:any) { 

    let clients = searchClient(); //array with clients
    
    if(client.id) {
        //edit - search by id & replace
        let index = clients.findIndex((c:any) => c.id == client.id);
        clients[index] = client;

    }else {
        //new - generates id & does a push to the array
        client.id = Math.round(Math.random()*10000);
        clients.push(client);

    }
    clients.push(client); //in that array we add the client we recive [].push(client)
    localStorage['clients'] = JSON.stringify(clients); //we transform it into a string
}

问题原因与解决方法

1. 重复条目核心原因

saveClient函数末尾的clients.push(client);是多余的:

  • 编辑场景:已经通过clients[index] = client替换了原条目,再执行push会新增一条重复数据;
  • 新增场景:已经在else分支里执行了clients.push(client),末尾再push一次导致重复。

修复后的saveClient函数:

export function saveClient(client:any) { 

    let clients = searchClient(); //array with clients
    
    if(client.id) {
        //edit - search by id & replace
        let index = clients.findIndex((c:any) => c.id == client.id);
        clients[index] = client;

    }else {
        //new - generates id & does a push to the array
        client.id = Math.round(Math.random()*10000);
        clients.push(client);

    }
    // 移除多余的push语句
    localStorage['clients'] = JSON.stringify(clients); //we transform it into a string
}

2. 额外优化:React State不可变操作问题

editClient.tsx中直接修改state对象的方式不符合React状态管理规范,可能导致输入变更不触发组件重渲染:

// 错误写法:直接修改state对象,不会触发组件重渲染
<IonInput onIonChange={e => client.firstname = e.detail.value} value={client.firstname}></IonInput>

正确写法:使用setClient创建新对象更新状态:

<IonInput 
  onIonChange={e => setClient(prev => ({...prev, firstname: e.detail.value}))} 
  value={client.firstname}
></IonInput>

所有输入框的onIonChange都需要改成这种方式,确保输入变更能正确触发组件更新,避免数据不同步问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:05:23