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

ReactJS:如何从子组件的状态中获取选中值?

解决方案:获取Select组件选中值的两种方式

推荐方案:状态提升至App组件(符合React单向数据流)

React中,当多个组件需要共享或访问同一状态时,状态提升是标准做法。把Select的选中状态移到App组件后,父组件可以直接拿到选中值,点击按钮打印就很简单。

修改后的App组件代码:

import React, { useState } from "react";
import { Button } from "@mui/material";
import SelectVariant from "./Components/SelectVariant";
import { category } from "./data";

function App() {
  // 将选中状态托管在App组件中
  const [selectedCategory, setSelectedCategory] = useState('');

  // 按钮点击事件:打印选中值
  const handleGetClick = () => {
    console.log('当前选中值:', selectedCategory);
  };

  return(
    <div>
      <SelectVariant 
        values={category}
        name="Category"
        // 传递当前选中值给子组件
        value={selectedCategory}
        // 传递状态更新函数给子组件
        onChange={setSelectedCategory}
      />

      <Button variant="contained" onClick={handleGetClick}>Get</Button>
    </div>
  )     
}

export default App;

修改后的SelectVariant组件代码:

将组件改为受控组件,不再维护内部状态,完全依赖父组件传入的value和onChange:

import * as React from 'react';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import Select from '@mui/material/Select';

export default function SelectVariant(props) {
  const handleChange = (event) => {
    // 调用父组件传递的onChange函数更新状态
    props.onChange(event.target.value);
  };

  const menuItems = props.values.map(ele => (
    <MenuItem key={ele} value={ele}>{ele}</MenuItem>
  ))

  return (
    <FormControl sx={{ m: 1, minWidth: 120 }} size="small">
      <InputLabel id="demo-select-small">{props.name}</InputLabel>
      <Select
        labelId="demo-select-small"
        id="demo-select-small"
        value={props.value}
        label={props.name}
        onChange={handleChange}
      >
        {menuItems}
      </Select>
    </FormControl>
  );
}

备选方案:使用Ref访问子组件内部状态(不推荐)

如果不想修改状态结构,可以通过useRef和forwardRef获取子组件的内部状态,但这种方式会增加组件耦合度,不利于后续维护,仅适合临时场景。

修改后的App组件代码:

import React, { useRef } from "react";
import { Button } from "@mui/material";
import SelectVariant from "./Components/SelectVariant";
import { category } from "./data";

function App() {
  const selectRef = useRef(null);

  const handleGetClick = () => {
    // 通过ref访问子组件暴露的状态
    console.log('当前选中值:', selectRef.current?.category);
  };

  return(
    <div>
      <SelectVariant 
        ref={selectRef}
        values={category}
        name="Category"
      />

      <Button variant="contained" onClick={handleGetClick}>Get</Button>
    </div>
  )     
}

export default App;

修改后的SelectVariant组件代码:

使用forwardRef和useImperativeHandle暴露内部状态:

import * as React from 'react';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import Select from '@mui/material/Select';

// 用forwardRef包裹组件,允许父组件传递ref
const SelectVariant = React.forwardRef((props, ref) => {
  const [category, setCategory] = React.useState('');

  // 暴露指定属性给父组件的ref
  React.useImperativeHandle(ref, () => ({
    category
  }));

  const handleChange = (event) => {
    setCategory(event.target.value);
  };

  const menuItems = props.values.map(ele => (
    <MenuItem key={ele} value={ele}>{ele}</MenuItem>
  ))

  return (
    <FormControl sx={{ m: 1, minWidth: 120 }} size="small">
      <InputLabel id="demo-select-small">{props.name}</InputLabel>
      <Select
        labelId="demo-select-small"
        id="demo-select-small"
        value={category}
        label={props.name}
        onChange={handleChange}
      >
        {menuItems}
      </Select>
    </FormControl>
  );
});

export default SelectVariant;

方案对比

  • 状态提升:符合React单向数据流,组件解耦,便于维护和扩展,优先选择。
  • Ref访问:组件耦合度高,子组件内部状态变化会影响父组件,仅在特殊场景下使用。

内容的提问来源于stack exchange,提问作者FloydK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:37:23