React类组件使用react-modal报错:无效Hook调用、setAppElement参数无效
问题1 解决Error: Invalid hook call.报错
该报错的核心原因是违反了React Hook的使用规则:Hook只能在函数组件、自定义Hook的顶层作用域调用。你当前使用的是Class类组件,useState属于Hook,不能在类组件的render方法内调用,有两种修复方案:
- 方案1:将整个FeaturedCards组件重构为函数组件,重构完成后把
const [modalIsOpen, setIsOpen] = useState(false)放在函数组件的顶层(return语句之前,不在任何循环、条件判断、嵌套函数内)即可正常使用。 - 方案2:保留类组件写法,移除
useState调用,把模态框相关状态放到类的state中管理:- 在constructor的state配置中新增模态框状态、当前选中的列表项状态:
constructor() { super(); this.state = { name: 'React', apiData: [], modalIsOpen: false, activeItem: null }; // 绑定方法this指向 this.handleClick = this.handleClick.bind(this); this.closeModal = this.closeModal.bind(this); this.afterOpenModal = this.afterOpenModal.bind(this); }- 将handleClick、closeModal、afterOpenModal改为类的实例方法,用
this.setState修改状态:
handleClick(item) { this.setState({ modalIsOpen: true, activeItem: item }); } closeModal() { this.setState({ modalIsOpen: false, activeItem: null }); } afterOpenModal() { this.subtitle.style.color = '#f00'; }- 将Modal组件从
map循环中移出,放到CardColumns同级的位置,Modal内可以直接读取this.state.activeItem渲染对应内容,避免给每个列表项都生成冗余的Modal实例。
问题2 Modal.setAppElement正确入参说明
该方法的作用是指定应用的根DOM元素,用于无障碍适配:模态框打开时会自动隐藏根元素的屏幕阅读器读取权限,避免读屏设备识别到模态框背后的内容。
你之前传入组件名FeaturedCards是无效的,该方法支持两种入参格式:
- 有效的CSS选择器字符串,绝大多数React项目的根DOM元素id为
root,直接传'#root'即可生效。 - 直接传入DOM元素实例,如果你需要绑定到当前组件的根节点,可以给render返回的最外层div添加id属性,比如
<div id="featured-cards-container">,然后在componentDidMount生命周期中调用:
componentDidMount() { Modal.setAppElement(document.getElementById('featured-cards-container')); // 原有接口请求逻辑保留 }
方法调用时机建议放在组件导入之后、组件定义之前,或者类组件的componentDidMount生命周期内,不要放在render方法中重复执行。
内容的提问来源于stack exchange,提问作者Randy
相关产品推荐
相关产品推荐

