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

React中如何调用另一个组件的事件方法

解决方案

核心修改思路

  • React中父子组件通信最基础的方式就是通过props传递回调函数,你可以在渲染Camera组件时,把ShowScanner的handleHideClick方法作为参数传给Camera
  • 修复状态不同步问题:你之前手动卸载Camera时没有更新ShowScanner的showCamera状态,导致按钮点击逻辑异常,需要点击两次才能重新打开摄像头
  • 修复setState异步导致的读取result值不准确的问题

修改后完整代码

import React from 'react';
import QrReader from 'react-qr-reader';
import { unmountComponentAtNode, render } from "react-dom";

class Camera extends React.Component {
    state = {
        result: 'No result'
    }

    handleScan = data => {
        if (data) {
            this.setState({
                result: data
            });
            // setState是异步的,直接用拿到的data更稳妥,也可以写在setState的第二个回调参数里
            scanDataProcessor(data);
            // 调用父组件传过来的隐藏方法,不需要自己手动卸载组件
            this.props.onScanSuccess();
        }
    }
    handleError = err => {
        console.error(err)
    }
    render() {
        return (
            <div id="scanner" class="">
                <QrReader
                    delay={300}
                    onError={this.handleError}
                    onScan={this.handleScan}
                    style={{ width: '100%' }}
                />
            </div>
        )
    }
}

class ShowScanner extends React.Component {
    constructor(props) {
        super(props);
        this.handleShowClick = this.handleShowClick.bind(this);
        this.handleHideClick = this.handleHideClick.bind(this);
        this.state = { showCamera: false }
    }

    handleShowClick() {
        this.setState({ showCamera: true });
        // 渲染Camera时把隐藏方法作为props传入
        render(<Camera onScanSuccess={this.handleHideClick} />, document.getElementById('root'));
    }

    handleHideClick() {
        this.setState({ showCamera: false });
        unmountComponentAtNode(document.getElementById('root'));
    }

    render() {
        const showCamera = this.state.showCamera;
        // 优化重复的按钮代码,不需要写两遍相同的按钮
        return (
            <button id="btnScan" type="button" class="btn btn-primary p-1" onClick={showCamera ? this.handleHideClick : this.handleShowClick}>
                <i class="bi bi-qr-code-scan"></i>
                <br />Scan
            </button>
        );
    }

}
render(<ShowScanner />, document.getElementById('scanBtn'));

逻辑说明

  1. 扫描成功后Camera调用传入的onScanSuccess回调,也就是ShowScanner的handleHideClick方法,会同时做两件事:更新showCamera状态为false、卸载root节点的Camera组件,状态完全同步
  2. 下次用户点击按钮时,因为showCamera已经是false,会直接触发handleShowClick逻辑,重新渲染Camera组件,不需要点击两次
  3. 避开了setState异步的坑,直接用扫描返回的data参数传给scanDataProcessor,不会出现读取到旧值的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:36:07