如何在具有React钩子的复选框之一上使用onChange事件在map函数内部操作DOM

时间:2019-11-25 06:10:53

标签: javascript reactjs react-hooks

因此,首先我从另一个文件中导入一个非常简单的“数据库”对象,该文件中具有一个学生数组属性。之后,我将遍历students数组以在window对象上显示所有学生。一切顺利,直到每次当状态从status更改为true时,我都试图在map函数内部的div标签之一上动态更改类名时,我要显示信息,否则div应该保持不可见。在实现以下代码并尝试在框上打勾后,我得到了错误“无法在布尔值'true'上创建属性'0'”。请告诉我我在做什么错。谢谢您对此案的关注。

import React,{ useState,useEffect } from 'react'
import db from './db'
import './App.css'

const App = () => {
 const [status,setStatus] = useState(database.map((student) => {
   return student.isChecked
 }))
 return db.students.map(({name,id,email,isChecked}, index) => {
    return (
      <form key={id} className='form'>
        <h2>
          {name}
        </h2>
        <select name='student_attendance' className='form__dropdown' defaultValue='present'>
          <option value='present'>
            present
          </option>
          <option value='absent'>absent</option>
        </select>
        <div>
          <label htmlFor={id}>Left early</label>
          <input type='checkbox' name='leftEarly' id={id} />
        </div>
        <div>
          <label htmlFor={email}>Arrival late</label>
          <input type='checkbox' name='arrivalLate' id={email} onChange=                 {(event) => {
              setStatus(status =>
                status[index] = event.currentTarget.checked
                )
            }}/>
        </div>
         <div className={status[index] ? 'visible' : 'invisible'>
           <p>time: </p>
         </div>
      </form>
    )
  })
}

export default App
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

1 个答案:

答案 0 :(得分:1)

setStatus的参数应为:

  • status的新值

  • 采用先前版本status并返回新版本的函数

您正在向其传递一个函数,该函数修改所接收的status值,然后返回一个布尔值。因此,看来status更改为该布尔值,然后status[index]表达式中的className实际上正在评估true[0],从而导致错误。

要解决此问题,请修复对setStatus()函数的使用:

setStatus(status => [
    ...status.slice(0, index),     
    event.currentTarget.checked,
    ...status.slice(index + 1)
])

您可能还想尝试一下,它不依赖于event属性:

setStatus(status => [
    ...status.slice(0, index),     
    !status[index],
    ...status.slice(index + 1)
])

甚至是这样:

setStatus(status => 
    status.map((x, i) => (i === index) ? !x : x)
)