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

React.js中点击div时如何获取元素的文本内容?

解决React子组件点击后传递内容到父组件的问题

我来帮你搞定这个问题~你现在的困境主要是既用了不符合React设计思路的DOM操作,还不小心犯了语法错误,咱们一步步来修正,用更React的方式实现需求。

先说说你现有代码为啥不工作

  • document.getElementsByClassName(".recipe-name") 这里多了个多余的点号!这个方法接收的是不带点的类名字符串,而且它返回的是一个HTMLCollection集合(类似数组的结构),不是单个元素,所以哪怕去掉点号,你也得用document.getElementsByClassName("recipe-name")[0]?.textContent才能拿到第一个匹配元素的文本。但说实话,这种直接操作DOM的方式在React里真的不推荐,违背了React的数据流设计。
  • 你之前尝试用ref但没成功,大概率是ref的创建和引用方式不对,但同样,ref更适合用来处理DOM元素的交互(比如聚焦、滚动),而不是用来传递组件数据。

推荐方案:用回调函数实现组件间通信

React的核心是单向数据流,子组件应该通过父组件传递的回调函数把数据“递”回去,而不是让父组件直接伸手去子组件里拿DOM内容。这是React组件通信的标准做法,代码更清晰也更好维护。

第一步:改造子组件,添加点击事件并传递数据

在子组件的recipe-container div上绑定点击事件,把需要的菜谱名和食材数据整理好,通过父组件传过来的回调函数发回去:

export default class Recipecontainer extends React.Component {
  handleContainerClick = () => {
    const { recipe, onRecipeClick } = this.props;
    // 把需要的数据整理成你需要的格式,比如对象
    const recipeInfo = {
      recipeName: recipe.recipeName,
      ingredients: recipe.ingredients.join('\n') // 用换行分隔食材,或者换成', '也可以
    };
    // 调用父组件的回调,把数据传过去
    onRecipeClick(recipeInfo);
  };

  render(){
    const recipe = this.props.recipe;
    const recipeIngredients = recipe.ingredients.map((item, index) => <li key={index}>{item}</li>);
    return (
      {/* 给容器div绑定点击事件 */}
      <div className="recipe-container" onClick={this.handleContainerClick}>
        <h3 className="recipe-name">{recipe.recipeName}</h3>
        <div className="food-img">
          <img src={recipe.smallImageUrls} alt="菜谱图片"/>
        </div>
        <ul className="ingredient-list">{recipeIngredients}</ul>
      </div>
    )
  }
}

第二步:父组件接收数据并存储

父组件需要定义一个处理数据的方法,然后把这个方法作为props传给子组件。当子组件被点击时,这个方法就会接收到子组件传递的菜谱数据,你就可以把它存在state或者变量里了:

export default class ParentComponent extends React.Component {
  // 用state存储选中的菜谱数据,这样数据变化时组件会自动更新
  state = {
    selectedRecipe: null
  };

  saveData = (recipeInfo) => {
    // 这里拿到子组件传过来的数据,存到state里
    this.setState({ selectedRecipe: recipeInfo });
    // 也可以做其他操作,比如打印看看
    console.log('选中的菜谱信息:', recipeInfo);
  };

  render() {
    // 假设你有一个菜谱数组,循环渲染子组件
    const recipes = []; // 这里替换成你的菜谱数据源
    return (
      <div className="parent-wrapper">
        {recipes.map((recipe, idx) => (
          <Recipecontainer 
            key={idx} 
            recipe={recipe} 
            onRecipeClick={this.saveData} // 把回调函数传给子组件
          />
        ))}
        {/* 可以在这里展示选中的菜谱内容 */}
        {this.state.selectedRecipe && (
          <div className="selected-recipe-card">
            <h4>你选中的菜谱:{this.state.selectedRecipe.recipeName}</h4>
            <p>所需食材:<br/>{this.state.selectedRecipe.ingredients}</p>
          </div>
        )}
      </div>
    );
  }
}

如果你非要用ref的方式(不推荐,但可以实现)

如果你坚持想用ref来获取DOM内容,也能实现,但真的不建议这么做:

// 子组件修改
export default class Recipecontainer extends React.Component {
  // 创建一个ref绑定到容器div
  containerRef = React.createRef();

  handleContainerClick = () => {
    const container = this.containerRef.current;
    if (!container) return;
    // 通过ref获取DOM元素的内容
    const recipeName = container.querySelector('.recipe-name').textContent;
    const ingredients = container.querySelector('.ingredient-list').textContent;
    // 还是通过回调传给父组件
    this.props.onRecipeClick({ recipeName, ingredients });
  };

  render(){
    const recipe = this.props.recipe;
    const recipeIngredients = recipe.ingredients.map((item, index) => <li key={index}>{item}</li>);
    return (
      <div className="recipe-container" ref={this.containerRef} onClick={this.handleContainerClick}>
        {/* 其他内容不变 */}
      </div>
    )
  }
}

父组件的用法和上面完全一样,还是通过onRecipeClick接收数据。

最后总结一下

强烈推荐用回调函数传递数据的方式,这是React的标准玩法,既符合单向数据流的设计,代码也更易读易维护。直接操作DOM的方式容易引发意想不到的问题,尤其是在组件重新渲染的时候。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:33:31