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

React:使用refs从祖父组件读取子组件textarea的值

解决祖父组件获取子组件textarea值的问题

这个问题我之前也碰到过,核心原因是React的ref是组件局部作用域的——子组件里声明的ref="someref"只属于子组件自己,祖父组件的this.refs里根本不会有这个引用,所以你用ReactDOM.findDOMNode(this.refs.someref)返回null是完全正常的。

下面给你两种可行的解决方案,优先推荐第一种,更符合React的设计理念:

方案一:用受控组件(最推荐)

你的子组件里的textarea已经是受控组件了(用到了props.value和props.onChange),那我们只需要把状态提升到祖父组件,通过props层层传递,就能直接在祖父组件里拿到textarea的值,完全不需要依赖ref。

举个完整的例子:

祖父组件

class Grandparent extends React.Component {
  constructor(props) {
    super(props);
    // 把textarea的值存在祖父组件的state里
    this.state = { textareaContent: '' };
    this.handleTextChange = this.handleTextChange.bind(this);
    this.logTextValue = this.logTextValue.bind(this);
  }

  // 处理textarea的变化,更新state
  handleTextChange(e) {
    this.setState({ textareaContent: e.target.value });
  }

  // 你需要的函数,直接从state里取值就行
  logTextValue() {
    console.log('当前textarea的值:', this.state.textareaContent);
  }

  render() {
    return (
      <div>
        {/* 把onChange和value传递给父组件 */}
        <Parent onChange={this.handleTextChange} value={this.state.textareaContent} />
        <button onClick={this.logTextValue}>打印textarea值</button>
      </div>
    );
  }
}

父组件

父组件只需要把接收到的props透传给子组件就行:

class Parent extends React.Component {
  render() {
    return <Child onChange={this.props.onChange} value={this.props.value} />;
  }
}

子组件

保持你原来的结构就行,不需要额外修改:

class Child extends React.Component {
  render() {
    return (
      <textarea
        name={this.props.name}
        id={this.props.id}
        onChange={this.props.onChange}
        value={this.props.value}
      />
    );
  }
}

这样一来,祖父组件的logTextValue函数直接访问this.state.textareaContent就能拿到textarea的实时值,数据流清晰,也更容易维护。

方案二:用Ref转发(适合非受控场景)

如果你确实需要通过ref直接获取textarea的DOM元素,可以用React.forwardRef把子组件的ref转发给祖父组件,不过这种方式更适合非受控组件的场景。

子组件(用forwardRef包裹)

把子组件改成函数组件并包裹在forwardRef里,把ref绑定到textarea上:

const Child = React.forwardRef((props, ref) => {
  return (
    <textarea
      name={props.name}
      id={props.id}
      onChange={props.onChange}
      value={props.value}
      ref={ref} // 把外部传入的ref绑定到textarea
    />
  );
});

父组件(透传ref)

父组件也需要用forwardRef来透传ref给子组件:

const Parent = React.forwardRef((props, ref) => {
  return <Child {...props} ref={ref} />;
});

祖父组件

创建一个ref并传递给父组件,之后就能通过ref访问textarea元素:

class Grandparent extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个ref对象
    this.textareaRef = React.createRef();
    this.logTextValue = this.logTextValue.bind(this);
  }

  logTextValue() {
    // 通过ref.current拿到textarea DOM元素
    if (this.textareaRef.current) {
      console.log('当前textarea的值:', this.textareaRef.current.value);
    }
  }

  render() {
    return (
      <div>
        <Parent ref={this.textareaRef} />
        <button onClick={this.logTextValue}>打印textarea值</button>
      </div>
    );
  }
}

如果父组件是类组件,没办法直接接收forwardRef传递的ref,你可以把ref作为普通props传递(比如叫innerRef),然后在父组件里把props.innerRef传递给子组件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:22:50