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

React中点击调用并传参至另一组件的问题求助

如何在React中通过点击事件唤起编辑组件并传递参数

嘿,我明白你现在的困扰了——你想在点击EDIT按钮后,把选中的分类数据传给编辑组件并显示出来,但之前的尝试没达到预期。其实问题出在你用了手动调用ReactDOM.render的方式,这不符合React的声明式渲染思路,咱们换个更合理的方式来实现:

核心思路

在React里,组件的显示/隐藏和数据传递应该通过状态控制来实现,而不是手动去渲染组件。我们可以在CategoryList里维护一个状态,用来控制编辑模态框的显示,同时保存选中的分类数据,然后把这些数据作为props传给CategoryEdit组件。

修改后的完整代码

1. 调整CategoryList组件

class CategoryList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      pageInfo: [],
      // 新增两个状态:控制模态框显示、保存选中的分类
      isEditModalOpen: false,
      selectedCategory: {}
    };
    // 绑定方法,避免this指向问题
    this.editCategory = this.editCategory.bind(this);
    this.closeEditModal = this.closeEditModal.bind(this);
  }

  componentDidMount() {
    // 这里读取数据的逻辑保持不变
  }

  editCategory(category) {
    // 只需要更新状态:保存选中的分类,打开模态框
    this.setState({
      selectedCategory: category,
      isEditModalOpen: true
    });
  }

  closeEditModal() {
    // 关闭模态框
    this.setState({ isEditModalOpen: false });
  }

  renderCategories() {
    return this.state.data.map(category => {
      return (
        <tr id={"one-row-" + category.id} key={category.id}>
          <td>{category.id}</td>
          <td>{category.name}</td>
          <td>{category.title}</td>
          <td>{category.description}</td>
          <td>
            <a 
              className="btn btn-primary btn-sm" 
              data-toggle="modal" 
              href="#edit-modal" 
              title="EDIT" 
              onClick={(e) => this.editCategory(category)}
            >
              EDIT
            </a>
          </td>
        </tr>
      )
    })
  }

  render() {
    return (
      <div>
        <h1 className="text-center">Categories</h1>
        <hr />
        <table className="table table-bordered table-striped table-hovered table-sortable">
          <thead>
            <tr>
              <th>id</th>
              <th>name</th>
              <th>title</th>
              <th>desc</th>
            </tr>
          </thead>
          <tbody>
            {this.renderCategories()}
          </tbody>
        </table>

        {/* 编辑模态框,根据isEditModalOpen控制显示 */}
        {this.state.isEditModalOpen && (
          <div className="modal fade show" style={{ display: 'block' }}>
            <div className="modal-dialog">
              <div className="modal-content" id="pop-up-content">
                <div className="modal-header">
                  <h5 className="modal-title">编辑分类</h5>
                  <button type="button" className="close" onClick={this.closeEditModal}>
                    <span>&times;</span>
                  </button>
                </div>
                <div className="modal-body">
                  {/* 把选中的分类数据作为props传给CategoryEdit */}
                  <CategoryEdit category={this.state.selectedCategory} />
                </div>
              </div>
            </div>
          </div>
        )}
      </div>
    );
  }
}

ReactDOM.render(
  <CategoryList subreddit="catgories" />,
  document.getElementById('root')
);

2. 调整CategoryEdit组件

class CategoryEdit extends React.Component {
  constructor(props) {
    super(props);
    // 从props获取初始的分类数据,同步到组件状态
    this.state = { ...this.props.category };
    // 绑定方法
    this.editRow = this.editRow.bind(this);
  }

  // 如果props更新(比如选中了另一个分类),同步到state
  componentDidUpdate(prevProps) {
    if (prevProps.category.id !== this.props.category.id) {
      this.setState({ ...this.props.category });
    }
  }

  editRow() {
    const { id } = this.state;
    // 建议用React的受控组件获取值,而不是直接操作DOM
    const name = document.getElementById("edit-name").value;
    const title = document.getElementById("edit-title").value;
    const description = document.getElementById("edit-description").value;
    const subTitle = document.getElementById("edit-subTitle").value;
    const imagePath = document.getElementById("edit-imagePath").value;
    const tags = document.getElementById("edit-tags").value;

    $.ajax({
      url: "http://localhost:49384/api/CategoryEdit",
      method: "POST",
      data: {
        Id: id, 
        Name: name, 
        Title: title, 
        Description: description, 
        SubTitle: subTitle, 
        ImagePath: imagePath, 
        Tags: tags 
      },
      dataType: "json",
      // 用箭头函数,确保this指向组件实例
      success: (result) => {
        if (result != null) {
          alert(result.message);
          if (result.isSuccess === true) {
            this.setState({
              id: id,
              name: name,
              title: title,
              description: description,
              subTitle: subTitle,
              imagePath: imagePath,
              tags: tags
            });
            // 可以在这里通知父组件更新列表,比如调用props里的回调
            // this.props.onUpdate();
          }
        }
      }
    });
  }

  render() {
    return (
      <div>
        {/* 这里写你的编辑表单UI,示例如下: */}
        <div className="form-group">
          <label>Name</label>
          <input 
            type="text" 
            className="form-control" 
            id="edit-name" 
            defaultValue={this.state.name} 
          />
        </div>
        {/* 其他表单字段类似,用this.state里的值填充 */}
        <button type="button" className="btn btn-success" onClick={this.editRow}>
          保存修改
        </button>
      </div>
    )
  }
}

为什么之前的方法不对?

你之前在setState回调里手动调用ReactDOM.render,相当于绕过了React的组件树状态管理,这样CategoryEdit无法响应CategoryList的状态变化,而且当你再次点击其他分类时,也不能正确更新数据。用状态控制的方式,完全符合React的声明式渲染理念,组件会自动根据状态变化重新渲染。

另外,建议你把表单改成受控组件(即表单值和组件状态绑定),这样就不用直接操作DOM获取输入值,更符合React的最佳实践。

内容的提问来源于stack exchange,提问作者A.J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 08:57:47