【问题标题】:Problem twice click on submit handler in React JS问题两次单击 React JS 中的提交处理程序
【发布时间】:2021-03-10 16:00:03
【问题描述】:

我是新的反应。我想在模态中创建一个提交表单。但我遇到了一些问题。

在我的表单中有文本框和多个复选框(数组对象),如果我在此复选框中给出一个事件,它将添加新键(IsChecked = true)。当我尝试通过单击按钮提交表单时,问题出现了,第一次单击它不起作用(useState 上的新参数未更新),但是当我单击两次时它起作用(useState 更新了新参数)。

这是我的代码:

import React, {useState,useEffect} from 'react'
 
export default function Form() {
    const listNav = [{ID:'1',Name:'Dashboard'},{ID:'2',Name:'Profile'}];
    const [NIP,setNIP] = useState("");
    const [NavArray,setNav] = useState(listNav);
    const [messagePost, setMsgPost] = useState("");
    const [error, setMsgError] = useState("");

    const handleNavParent = (id,e) =>{
        let ischecked = e.target.checked;
        if(ischecked){
            const checkBoxArray = NavArray;
            const index = checkBoxArray.findIndex(object => object.ID === id);
            checkBoxArray[index].IsChecked = !checkBoxArray[index].IsChecked;
            setNav(checkBoxArray);
        }
    }

    const submitHandler =  e => {
        e.preventDefault();
        if(NIP && NavArray && countChk > 0){
            let dataParam = {NIP:NIP, NavArray: NavArray};
            console.log(dataParam);
            
            setMsgError("");
        }else{
            setMsgError("Please fill up the form with correctly.");
        }
    }

    return (
        <form id="form-user-access" autoComplete="off" onSubmit={submitHandler}>
          <input type="text" name="NIP" pattern="[0-9]*" onInput={(e)=>handleNumber(e)} value={NIP} className="form-control form-control-sm" />
           {   listNav.map((v) => (
                    <div className="col-sm-6">
                        <div className="card card-custome gutter-b">
                            <div className="card-body p-2">
                                <p className="text-info">{v.TypeName} menu</p>
                                <label className="font-size-sm"><input type="checkbox" value={v.ID} id={v.ID} onChange={(e)=>{handleNavParent(v.ID,e)}} /> {v.Name}</label>                                
                            </div>
                        </div>                        
                    </div>
                ))}
            <button className="btn btn-primary" type="submit">Save changes</button>
        </form>
    )
}

submitHandler()函数中,当我提交表单时(我勾选Dasboard(复选框)的条件),第一次点击它显示:

[NIP:123,NavArray:[{ID:'1',Name:'Dashboard'},{ID:'2',Name:'Profile'}]]

当我点击它或再次提交时,它会显示:

[NIP:123,NavArray:[{ID:'1',Name:'Dashboard',IsChecked:true},{ID:'2',Name:'Profile'}]]

我想做的是得到第二次点击的结果,但只有一次点击/提交。 如何修复我的代码?

【问题讨论】:

  • 提交处理程序在哪里更新NavArray 状态?还是我误会了什么?
  • @DrewReese 当点击 handleNavParent() 中的复选框时,NavArray 会更新。在该函数中有 setNav()。 SetNav 是更新 NavArray 的处理程序。

标签: javascript reactjs


【解决方案1】:

问题

您正在改变handleNavParent 中的状态对象。

const handleNavParent = (id, e) =>{
  let ischecked = e.target.checked;
  if (ischecked) {
    const checkBoxArray = NavArray; // <-- state reference
    const index = checkBoxArray.findIndex(object => object.ID === id);
    checkBoxArray[index].IsChecked = !checkBoxArray[index].IsChecked; // <-- state mutation!
    setNav(checkBoxArray); // <-- saved reference back into state
  }
}

这不会触发重新渲染,因为 NavArray 数组引用从未更新为 new 数组引用。在您单击提交表单并且submitHandler 调用setMsgError 并更新状态并触发具有上述副作用的重新渲染之前,您不会看到更新的状态。

解决方案

使用功能状态更新来切换选中的值。

const handleNavParent = (id, e) =>{
  const { checked } = e.target;

  if (checked) {
    setNav(state => state.map(el => el.ID === id ? {
      ...el,
      IsChecked: !el.IsChecked,
    } : el));
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-07
    • 2014-09-26
    • 2016-08-27
    • 1970-01-01
    • 2017-08-20
    • 2016-11-10
    • 2017-11-10
    • 1970-01-01
    相关资源
    最近更新 更多