You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 01:57:02