当前位置: 首页 > 知识库问答 >
问题:

前端 - 请教父组件和子组件状态传递和刷新的问题?

上官羽
2024-01-29

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

共有1个答案

岳永思
2024-01-29

状态都移到父组件即A上就可以了吧

// A.jsimport 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 (    <div class="A" onClick={closeMenu}>      <B toggleMenu={toggleMenu} isMenuOpen={isMenuOpen} />    </div>  );}export default A;
// B.jsimport React from 'react';const B = ({ toggleMenu, isMenuOpen }) => {  return (    <div>      <button className="preClass" onClick={toggleMenu}>        Open{' '}      </button>      {isMenuOpen && <div className="menubar">这里是菜单的内容</div>}    </div>  );};export default B;

stackblitz

报warning应该是因为这段代码Cannot update a component (A) while rendering a different component (B).

  • setLocalMenuOpencallback参数将会在rendering的时候执行。
  • isMenuOpenCallback(newLocalMenuOpen);会触发A组件的更新。

    setLocalMenuOpen(prevState => {   const newLocalMenuOpen = !prevState;   isMenuOpenCallback(newLocalMenuOpen);   return newLocalMenuOpen; });
 类似资料:
  • 我试图在我的应用程序中分解组件,但在理解如何将状态和道具从父组件传递给子组件时遇到了一些问题。对于上下文,“我的子组件”是一个表,它在行中呈现较小的组件。 现在我有一个名为BookComponents的常量,它需要一本书并写入状态。我被卡住的地方是传递状态和道具到我的书桌组件,这样我就可以在书桌上呈现书籍,而不是在主页上。 主页: 书桌代码:

  • 假设我的父组件有两个子组件: 我从Child2获得一个输入,并将其传递给父组件(到目前为止,我知道该怎么做)。但是,我需要将该输入传递给Child1,以更新它的状态。 我怎么能那么做?

  • 本文向大家介绍浅谈Vue父子组件和非父子组件传值问题,包括了浅谈Vue父子组件和非父子组件传值问题的使用技巧和注意事项,需要的朋友参考一下 本文介绍了浅谈Vue父子组件和非父子组件传值问题,分享给大家,具体如下: 1.如何创建组件 1.新建一个组件,如:在goods文件夹下新建goodsList.vue 2.在main.js中引入 import goodsList from 'goods/good

  • 执行了click事件后,为什么videoUrl的值在页面上更新了,控制台里没更新啊 想知道原因

  • 想要对一个父组件传递子组件: 传递children的时候: 是通过props 属性传递 还是通过组件的嵌套传递呢: