从其他函数组件调用ReactToPrint报Invalid hook call错误如何解决
报错原因
你遇到的Invalid hook call报错核心原因是违反了React Hook的调用规则:PrintInvoice是React函数组件,内部使用了useRef和useReactToPrint两个Hook,React要求Hook只能在函数组件渲染流程、自定义Hook两种场景下调用,你在Test5的onClick回调里直接执行PrintInvoice(),相当于在普通JS函数上下文内调用Hook,不符合规范直接触发报错。
修复方案
根据你的业务需求可以选择两种修复方式:
方案1:Test5直接渲染PrintInvoice组件
如果你需要在Test5页面展示打印内容和PrintInvoice自带的打印按钮,直接修改Test5.js代码即可:
import PrintInvoice from './PrintInvoice' function Test5() { return <PrintInvoice /> } export default Test5;
方案2:Test5自定义打印按钮触发打印
如果你只需要在Test5展示自己的打印按钮,隐藏PrintInvoice的内容和自带按钮,需要改造PrintInvoice通过ref暴露打印方法:
- 修改PrintInvoice.js代码:
import React, { useRef, forwardRef, useImperativeHandle } from 'react' import { useReactToPrint } from 'react-to-print'; class ComponentToPrint extends React.Component { render() { return ( <table> <thead> <th>column 1</th> <th>column 2</th> <th>column 3</th> </thead> <tbody> <tr> <td>data 1</td> <td>data 2</td> <td>data 3</td> </tr> </tbody> </table> ) } } const PrintInvoice = forwardRef((props, ref) => { const componentRef = useRef() const handlePrint = useReactToPrint({ content: () => componentRef.current }) // 暴露打印方法给父组件 useImperativeHandle(ref, () => ({ triggerPrint: handlePrint })) return ( <div style={{display: 'none'}}> <ComponentToPrint ref={componentRef} /> <button onClick={handlePrint}>Print</button> </div> ) }) export default PrintInvoice;
- 修改Test5.js代码:
import PrintInvoice from './PrintInvoice' import { useRef } from 'react' function Test5() { const printRef = useRef() return ( <> <PrintInvoice ref={printRef} /> <button onClick={() => printRef.current.triggerPrint()}>打印</button> </> ) } export default Test5;
注意事项
- 所有React组件必须通过JSX的
<Component />语法渲染,不能当成普通函数在事件回调、定时器等非渲染场景直接调用。 - 父组件需要调用子组件内部方法时,统一使用
forwardRef+useImperativeHandle的方案实现。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

