React中父组件如何获取Patient子组件的acuity评分并统计总和
解决方案
基于React单向数据流的特性,子组件向父组件传值需要通过父组件传递回调函数的方式实现,你可以按以下步骤修改代码:
1. 核心逻辑说明
你不需要通过querySelector操作DOM读取acuity值,React是数据驱动的,我们通过状态提升的方式,在父组件App中存储所有患者的acuity映射,子组件Patient每次计算出自身的acuity后,调用父组件传入的回调同步数据即可。
2. 修复后的完整代码
App.js
import React, { useState } from 'react' import './css/style.css'; import './css/reset.css'; import logo from "./assets/logo.svg"; import Patient from './Components/Patient'; function App() { // 存储每个房间对应的acuity值,key为房间号,value为acuity得分 const [patientAcuityMap, setPatientAcuityMap] = useState({}); const [nurse, setnurse] = useState(0); // 计算总acuity值 const totalAcuity = Object.values(patientAcuityMap).reduce((sum, val) => sum + val, 0); // 子组件调用的回调函数,更新单个患者的acuity值 const handleAcuityChange = (room, newAcuity) => { setPatientAcuityMap(prev => ({ ...prev, [room]: newAcuity })); }; // 点击生成按钮时计算需要的护士数量,这里可以根据你的业务规则修改 const renderScoreTotal = () => { // 示例规则:每10分acuity对应1个护士,可自行调整 const requireNurse = Math.ceil(totalAcuity / 10); setnurse(requireNurse); }; return ( <div className="App"> <main> <section className="Left_col Padding"> <img className="Center" src={logo} alt="" /> <h3>Staffing Matrix</h3> <h2>My Units</h2> <hr /> <ul> <li className="Active-unit">2N Med/Surg</li> <li>4N Behavioral Health</li> <li>Emergency Department</li> <li>8E Oncology</li> <li>7SW Neuro ICU</li> <li>8NW Neonatal ICU</li> </ul> <button className="Logout-btn">Log Out</button> </section> <section className="Upper_col Padding"> <div className="Date-container"> <div className="Day">Thursday,</div> <div className="Date">November 2nd 2021</div> </div> <div> <h2 className="Hospital-title">Sedona Medical Center</h2> <h3 className="Unit-title Active-unit">Medical Surgical Unit</h3> </div> </section> <section className="Content_container Padding"> {/* 可以在这里显示总acuity值 */} <p>总护理难度评分:{totalAcuity}</p> <table> <thead> <tr> <th>Room #</th> <th>Name</th> <th>Age</th> <th>Assistance</th> <th>Oriented</th> <th>Incontinent</th> <th>Intubated</th> <th>Acuity Score</th> </tr> </thead> <tbody> <Patient room={401} onAcuityChange={handleAcuityChange} /> <Patient room={402} onAcuityChange={handleAcuityChange} /> <Patient room={403} onAcuityChange={handleAcuityChange} /> <Patient room={404} onAcuityChange={handleAcuityChange} /> <Patient room={405} onAcuityChange={handleAcuityChange} /> <Patient room={406} onAcuityChange={handleAcuityChange} /> <Patient room={407} onAcuityChange={handleAcuityChange} /> <Patient room={408} onAcuityChange={handleAcuityChange} /> <Patient room={409} onAcuityChange={handleAcuityChange} /> <Patient room={410} onAcuityChange={handleAcuityChange} /> <Patient room={411} onAcuityChange={handleAcuityChange} /> <Patient room={412} onAcuityChange={handleAcuityChange} /> <Patient room={413} onAcuityChange={handleAcuityChange} /> <Patient room={414} onAcuityChange={handleAcuityChange} /> <Patient room={415} onAcuityChange={handleAcuityChange} /> <Patient room={416} onAcuityChange={handleAcuityChange} /> </tbody> </table> <button onClick={renderScoreTotal} className="Generate-btn"> Generate </button> <section className="Staff-ratios"> <div className="Staff-card"> <p className="Staff-title">Nurse</p> <p className="Staff-number">{ nurse }</p> </div> <div className="Staff-card"> <p className="Staff-title">CNA</p> <p className="Staff-number">3</p> </div> <div className="Staff-card"> <p className="Staff-title">Social Work</p> <p className="Staff-number">2</p> </div> <div className="Staff-card"> <p className="Staff-title">PT/OT</p> <p className="Staff-number">2</p> </div> <div className="Staff-card"> <p className="Staff-title">EVS</p> <p className="Staff-number">2</p> </div> <div className="Staff-card"> <p className="Staff-title">Provider</p> <p className="Staff-number">2</p> </div> </section> </section> </main> </div> ); } export default App;
Patient.js
import React, { useState, useEffect } from "react"; import FakePatient from "./PtNameGenerator"; import AgeNumber from "./AgeGenerator"; function Patient(props) { const [assistance, setAssistance ] =useState('na'); const [oriented, setOriented ] =useState('4'); const [incontinent, setIncontinent ] =useState('n'); const [intubated , setIntubated ] =useState('n'); let acuity = 0; // 修复原逻辑bug:else不要重置总acuity,仅对应维度加0即可 if (assistance === 'ind') { acuity += 1; } else if (assistance === 'sba') { acuity += 2; } else if (assistance === '1pa') { acuity += 3; } else if (assistance === '2pa') { acuity += 4; } if (oriented === "4") { acuity += 1; } else if (oriented === '3') { acuity += 2; } else if (oriented === '2') { acuity += 3; } else if (oriented === '1') { acuity += 4; } if (incontinent === "y") { acuity += 2; } else if (incontinent === 'n') { acuity += 1; } if (intubated === "y") { acuity += 4; } else if (intubated === 'n') { acuity += 1; }; // 监听所有影响acuity的状态变化,同步到父组件 useEffect(() => { props.onAcuityChange(props.room, acuity); }, [assistance, oriented, incontinent, intubated, props]); return <tr className="Patient-row"> <td className="Room-number"> {props.room} </td> <td> <FakePatient /> </td> <td> <p><AgeNumber/></p> </td> <td> <select name="assistance" onChange={event => setAssistance(event.target.value) }> <option value="na">Select</option> <option value="ind">Ind</option> <option value="sba">SBA</option> <option value="1pa">1PA</option> <option value="2pa">2PA</option> </select> </td> <td> <select name="oriented" onChange={event => setOriented(event.target.value) } > <option value="4">x4</option> <option value="3">x3</option> <option value="2">x2</option> <option value="1">x1</option> </select> </td> <td> <select name="incontinent" onChange={event => setIncontinent(event.target.value) }> <option value="n">N</option> <option value="y">Y</option> </select> </td> <td> <select name="intubated" onChange={event => setIntubated(event.target.value) }> <option value="n">N</option> <option value="y">Y</option> </select> </td> <td className="Acuity-Score"> <p className="AcuityScoreResult"> { acuity } </p> </td> </tr>; }; export default Patient;
3. 逻辑说明
- 父组件
App给每个Patient实例传入唯一的房间号和回调函数handleAcuityChange - 子组件
Patient每次更新选择项后重新计算acuity,通过useEffect监听状态变化,调用回调函数把当前房间号和acuity值传回父组件 - 父组件用对象存储所有房间的acuity值,总得分直接通过
reduce累加计算,不需要操作DOM - 点击生成按钮时可以根据总得分计算需要的医护人员数量,示例中给的是每10分对应1个护士,你可以根据实际业务规则修改计算逻辑
内容的提问来源于stack exchange,提问作者Ali Fares-Boulos
相关产品推荐
相关产品推荐

