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
相关产品推荐
相关产品推荐

