首页 > 解决方案 > 输入复选框对 onChange 函数没有反应

问题描述

无法让复选框对其 onChange 事件做出反应(复选框保持默认状态)。我在这里看到过类似的帖子,但似乎没有任何效果。我希望另一双眼睛可以帮助找出我的逻辑出了什么问题。

这是handleChange函数,以及父组件中的输入字段的初始值

const [accountData, setAccountData]=useState({accountType:'Free',  //default input value for text input
                                              accountStatus: false }) //default input for checkbox input

const handleSubmit={/*submitLogic*/}       

const handleChange = e =>{
         
const target = e.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
setAccountData({...accountData, [name]:value})
}

//passing the handle change as a prop to the EditView component\\
<EditView  handleChange={handleChange} handleSubmit={handleSubmit} data={accountData}/>

这是包含输入表单的子组件(关注的是复选框,因为文本输入字段对其 onChange 事件作出反应)。

const EditView = ({ handleChange, handleSubmit, data}) =>{
    
const isChecked=data.accountStatus;

<form onSubmit={handleSubmit}>
        <div className="form-row" >
                    <div className="form-group col-md-6">
                     < label htmlFor="accountType">Account Type:</label>
                       <input 
                           type="text"
                           className="form-control" 
                           id="accountType"
                           name="accountType"
                           value={data.accountType}
                            onChange={handleChange}/>
                           
                  </div>
                  <div className="form-group col-md-6">
                      < label htmlFor="accountStatus">Account Status:</label>
                      <div className="custom-control custom-switch">
                        <input 
                            type="checkbox"
                            className="custom-control-input "
                             id="accountStatus"
                             name='accountStatus'
                            checked={isChecked}
                            //value={isChecked}
                            onChange={handleChange}
                            
                            />
                  </div>
             </div>
       <button type='submit' >Submit</button>

</form>
}

我什至尝试创建一个不同的 onChange 句柄函数,但仍然遇到同样的问题。我在上面的代码中做错了什么使我的复选框不会从默认状态改变吗?

标签: javascriptreactjs

解决方案


传递给useState的值是状态的初始值。如果您想使用通过属性传递的值,而不在组件本身中管理它,请不要使用状态。

const EditView = ({handleChange, handleSubmit, data}) => {
  const isChecked = data.accountStatus;

  // ...
};

当您使用:

const [isChecked, setIsChecked] = useState(data.accountStatus);

你是说,我想isChecked在这个组件中管理,但是初始值设置为data.accountStatus. 因此data.accountStatus,稍后更改不会影响 的值isChecked,因为只能通过setIsChecked函数更改。


对问题进行编辑后复选框不起作用的原因是由于使用了 Bootstrap。当您使用自定义表单元素时,Bootstrap 将用一些视觉表示(样式元素)替换实际的输入元素。这意味着当您单击 Bootstrap 复选框/开关时,您实际上并没有单击输入。

为了解决这个问题,我建议使用将Bootstrap集成到 React 中的 React Bootstrap。这是一个工作示例(运行代码段后单击“整页”按钮以防止控制台输出与内容重叠):

const {useState} = React;
const {render} = ReactDOM;
const {Form} = ReactBootstrap;

function App() {
  const [accountData, setAccountData] = useState({
    accountType: "Free",
    accountStatus: false,
  });
  
  const handleChange = ({target}) => {
    const name  = target.name;
    const value = target.type == "checkbox" ? target.checked : target.value;
    setAccountData({...accountData, [name]: value});
  };
  
  console.log(accountData);
  return <EditView data={accountData} onChange={handleChange} />;
}

function EditView({data, onChange}) {
  return (
    <Form>
      <Form.Group>
        <Form.Label>Account Type:</Form.Label>
        <Form.Control
          id="accountType"
          name="accountType"
          type="text"
          value={data.accountType}
          onChange={onChange}
        />
      </Form.Group>
      <Form.Group>
        <Form.Label>Account Status:</Form.Label>
        <Form.Switch
          id="accountStatus"
          name="accountStatus"
          label=""
          checked={data.accountStatus}
          onChange={onChange}
        />
      </Form.Group>
    </Form>
  );
}

render(<App />, document.getElementById("root"));
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" />
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/react/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js"></script>
<div id="root"></div>


推荐阅读