请教父组件和子组件状态传递和刷新的问题?-灵析社区

ApplePro

大家好,组件 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 ( {localMenuOpen && ( 这里是菜单的内容 )} ) } 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 ( 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 组件的任何地方(菜单项除外),都能关闭菜单,有其它什么更合适的方法?

阅读量:193

点赞量:0

问AI
状态都移到父组件即A上就可以了吧 // A.js import React from 'react'; import B from './B.js'; function A() { const [isMenuOpen, setMenuOpen] = React.useState(false); const toggleMenu = () => { console.log('toggle', isMenuOpen); setMenuOpen(!isMenuOpen); }; const closeMenu = (event) => { if (event.target.closest('.menubar')) return; console.log('closeMenu'); if (isMenuOpen) setMenuOpen(false); }; return ( ); } export default A; // B.js import React from 'react'; const B = ({ toggleMenu, isMenuOpen }) => { return ( Open{' '} {isMenuOpen && 这里是菜单的内容} ); }; export default B; "stackblitz" (https://link.segmentfault.com/?enc=NId%2F5SbZpYCXlKNrfLe46Q%3D%3D.B2VDPqqVbsgfjunItbqhMMaVNkgNxbZN7MsBBePBdYdayvZnEY5ReDxDv6WeIOzaddt6wJgxQWZn9dfzLObpFF5RK9nUavJMp1HQTNrPWYE%3D) 报warning应该是因为这段代码"Cannot update a component (A) while rendering a different component (B)." * "setLocalMenuOpen"的"callback"参数将会在"rendering"的时候执行。 * "isMenuOpenCallback(newLocalMenuOpen);"会触发A组件的更新。setLocalMenuOpen(prevState => { const newLocalMenuOpen = !prevState; isMenuOpenCallback(newLocalMenuOpen); return newLocalMenuOpen; });