大家好,组件 B.jsx 的代码如下,大概意思是它里面有一个按钮,可以打开菜单,也可以关闭菜单,切换菜单的打开和关闭
const B = ({ isMenuOpen, isMenuOpenCallback }) => {
const [localMenuOpen, setLocalMenuOpen] = useState(false);
const toggleMenu = (event) => {
setLocalMenuOpen(prevState => {
const newLocalMenuOpen = !prevState;
isMenuOpenCallback(newLocalMenuOpen);
return newLocalMenuOpen;
});
};
useEffect(() => {
setLocalMenuOpen(isMenuOpen);
}, [isMenuOpen]);
return (
<div>
<button className="preClass" onClick={toggleMenu} />
{localMenuOpen && (
<div className="menubar">这里是菜单的内容</div>
)}
</div>
)
}
export default B
组件 A.jsx 是组件 B 的父组件,即 B 组件被 A 组件引用,部分代码如下
import B from './B'
const handlePageClick = (e) => {
if (!e.target.closest('.menubar') {
setIsMenuOpen(false);=
}
};
useEffect(() => {
// listener
document.addEventListener('click', handlePageClick);
// remove
return () => {
document.removeEventListener('click', handlePageClick);
};
}, [isMenuOpen]);
return (
<B
otherHandler={() => otherHandler('news')}
isMenuOpen={isMenuOpen}
isMenuOpenCallback={(newMenuOpen) => setIsMenuOpen(newMenuOpen)} />
)
}
这些代码实现了当 B 组件中的菜单展开后,点击其父组件 A 中页面任何地方,都能关闭该菜单。但现在遇到的问题是总是有错误警告
Warning: Cannot update a component (A
) while rendering a different component (B
). To locate the bad setState() call inside B
请问这个该怎么修复呢?
或者说我的需求是点击 B 组件中的按钮可以打开关闭菜单,当菜单打开时,点击 A 组件的任何地方(菜单项除外),都能关闭菜单,有其它什么更合适的方法?
状态都移到父组件即A上就可以了吧
stackblitz
报warning应该是因为这段代码
Cannot update a component (A) while rendering a different component (B).
setLocalMenuOpen
的callback
参数将会在rendering
的时候执行。isMenuOpenCallback(newLocalMenuOpen);
会触发A组件的更新。