React父组件如何获取子组件状态并统计所有子组件得分总和
解决方案
你当前子组件的numberRoutes是内部私有状态,父组件无法直接获取,最优方案是状态提升,将所有路线的计数状态移到父组件统一维护,父组件可直接遍历计算总得分。
修改后父组件代码
import { useState } from 'react'; const RouteScore = () => { const routes = [ { length: 1, score: 1 }, { length: 2, score: 2 }, { length: 3, score: 4 }, { length: 4, score: 7 }, { length: 6, score: 15 }, { length: 8, score: 21 }, ]; // 父组件统一存储各长度路线的选中数量 const [routeCount, setRouteCount] = useState( routes.reduce((acc, route) => { acc[route.length] = 0; return acc; }, {}) ); // 直接计算总得分 const totalScore = routes.reduce((sum, route) => { return sum + route.score * routeCount[route.length]; }, 0); const buttons = routes.map((route) => ( <RouteScoreButton length={route.length} score={route.score} key={route.length} numberRoutes={routeCount[route.length]} onNumberChange={(newNum) => { setRouteCount(prev => ({ ...prev, [route.length]: newNum })) }} /> )) return ( <div className="position-absolute top-50 start-50 translate-middle"> <div className="bg-light border border-primary rounded-3 px-4 py-4 opacity-75 text-center"> <table className="table"> <thead> <tr className="text-center"> <th scope="col">Route length</th> <th scope="col">Total routes</th> <th scope="col">Total score</th> </tr> </thead> <tbody className="text-center align-middle"> {buttons} </tbody> </table> <h3>Total score: {totalScore}</h3> </div> </div> ) }
修改后子组件代码
import { useMemo } from 'react'; const RouteScoreButton = (props) => { const score = useMemo(() => props.score * props.numberRoutes, [props.score, props.numberRoutes]) const increaseRoute = () => { props.onNumberChange(props.numberRoutes + 1) } const decreaseRoute = () => { props.numberRoutes > 0 && props.onNumberChange(props.numberRoutes - 1) } const handleChange = (e) => { let newValue = parseInt(e.target.value) if (isNaN(newValue)) { props.onNumberChange(0) } else { // 额外限制输入值不能为负数 props.onNumberChange(Math.max(0, newValue)) } } return ( <tr> <th> <h3>{props.length}</h3> </th> <th> <div className="input-group" role="group" aria-label="Basic example"> <button type="button" className="btn btn-primary" onClick={increaseRoute}>+</button> <input type="text" className="form-control text-center" style={{ width: '50px' }} value={props.numberRoutes} onChange={handleChange} /> <button type="button" className="btn btn-primary" onClick={decreaseRoute}>-</button> </div> </th> <th> <h3>{score}</h3> </th> </tr> ) }
说明
状态提升是React父子组件通信的常规方案,完全适配当前简单场景,无需引入Context、Redux等额外状态管理工具增加复杂度。
内容的提问来源于stack exchange,提问作者Joaquín
相关产品推荐
相关产品推荐

