Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ReactJS钩子-如何重新渲染其他组件_Reactjs_Typescript_React Hooks - Fatal编程技术网

ReactJS钩子-如何重新渲染其他组件

ReactJS钩子-如何重新渲染其他组件,reactjs,typescript,react-hooks,Reactjs,Typescript,React Hooks,我这里有三个组件。主组件包括其他两个组件。我想做的是,WebHeaderComponent中选择输入的更改将刷新sidemenucomponent布局。但当我尝试这样做时,会出现错误提示 MainComponent -> WebHeaderComponent -> SideMenuComponent MainComponent.tsx const { Content } = Layout; const MainComopnent: FunctionComponent =

我这里有三个组件。主组件包括其他两个组件。我想做的是,WebHeaderComponent中选择输入的更改将刷新sidemenucomponent布局。但当我尝试这样做时,会出现错误提示

MainComponent
  -> WebHeaderComponent
  -> SideMenuComponent
MainComponent.tsx

const { Content } = Layout;

const MainComopnent: FunctionComponent = () => {
  const [collapsed, setCollapsed] = useState(false);
  const [menuList, setMenuList] = useState([]);
  const services = useContext(ServicesContext);
  const { MenuService } = services;
  const { AuthenticationService } = services;

  useEffect(() => {
    const requestOption = {
      method: "post",
      body: JSON.stringify({
        userCode: AuthenticationService.getUserModel().userCode, 
        roleId: AuthenticationService.getUserModel().roleId
      })
    }

    MenuApi.getSideMenu(requestOption).then((result) => {
      console.log(result);
      const temp = MenuService.groupMenu(result);
      setMenuList(temp);
    });
  }, []);
  const value = { collapsed, setCollapsed };
  
  return (
    <SideMenuCollapsedContext.Provider value={value}>
      <Layout className="layout">
        <SideMenuComponent menuList={MenuService.getGroupMenu()}></SideMenuComponent>
        <Layout className="site-layout">
          <WebHeaderComponent></WebHeaderComponent>
          <Content
            className="site-layout-background"
            style={{
              margin: "24px 16px",
              padding: 24,
              minHeight: 280,
              overflowY: "scroll",
            }}
          >
            <AppRoutes />
          </Content>
        </Layout>
      </Layout>
    </SideMenuCollapsedContext.Provider>
  );
};
export default MainComopnent;
const { Header } = Layout;

const WebHeaderComponent  = () => {
  const services = useContext(ServicesContext);
  const { MenuService } = services;
  const { AuthenticationService } = services;
  const { UserInfoService } = services;
  const [userRoleList, setUserRoleList] =  useState<Array<any>>([]);
  const {collapsed, setCollapsed} = useContext(SideMenuCollapsedContext);

  const toggle = () => {
    setCollapsed(!collapsed);
  };

  useEffect(() => {
    const data = { userId: AuthenticationService.getUserModel().userId};
    SysUserApi.searchSysUserRole(data).then((res) => {
      setUserRoleList(res)
    })
  },[]);  

  const handleRoleChange = (selectedRoleId) => {
    console.log('before: ' + selectedRoleId);
    AuthenticationService.setRoleId(selectedRoleId);
    console.log('after: ' + AuthenticationService.getUserModel().roleId)
  }

  return (
    <Header className="site-layout-background" style={{ padding: 0 }}>
      {React.createElement(
        collapsed ? MenuUnfoldOutlined : MenuFoldOutlined,
        {
          className: "trigger",
          style: { paddingLeft: "10px", fontSize: "20px" },
          onClick: toggle,
        }
      )}

      <div
        style={{
          float: "right",
          paddingRight: "20px",
          display: "flex",
          alignItems: "center",
        }}
      >
          <div><span>用戶:{AuthenticationService.getUserModel().userName}</span></div>
          <div style={{ paddingLeft: "10px" }}>
            <span>公司-角色:</span>
            <Select 
              style={{ width: 120 }} 
              defaultValue={AuthenticationService.getUserModel().roleId}
              onChange={handleRoleChange}
            >
              {userRoleList.map(item => (
                <option
                  key={item.roleId}
                  value={item.roleId}
                >
                  {item.roleName}
                </option>
              ))}
            </Select>
          </div>
        <div style={{ paddingLeft: "10px" }}>
          <Button type="primary"> Sign Out </Button>
        </div>
      </div>
    </Header>
  );
}

export default WebHeaderComponent;
const { Sider } = Layout;
const { SubMenu } = Menu;

const createSubMenus = (menuList): any => {
  const menus: any = [];
  for (const subMenuItem of menuList) {
    if (subMenuItem.children && subMenuItem.children.length > 0) {
      menus.push(
        <SubMenu
          key={subMenuItem.funcId}
          title={
            <span>
              <MailOutlined />
              <span className="fontWt">{subMenuItem.funcName}</span>
            </span>
          }
        >
          {createSubMenus(subMenuItem.children)}
        </SubMenu>
      );
    } else {
      menus.push(
        <Menu.Item key={subMenuItem.funcId + subMenuItem.parentId}>
          {subMenuItem.funcName}
          <Link to={"/app" + subMenuItem.funcUrl} replace></Link>
        </Menu.Item>
      );
    }
  }
  return menus;
};

const SideMenuComponent = ({ menuList }) => {
  const value = useContext(SideMenuCollapsedContext);
  const [subMenuList, setSubMenuList] = useState([]);
  const { collapsed, setCollapsed } = value;

  useEffect(() => {
    setSubMenuList(createSubMenus(menuList));
  }, [menuList]);

  const handleCollapsed = (collapsed) => {
    setCollapsed(collapsed);
  };

  return (
    <Sider collapsible collapsed={collapsed} onCollapse={handleCollapsed}>
      <div className="logo" />
      <Menu theme="dark" mode="inline" defaultSelectedKeys={["1"]}>
        {/* <Menu.Item key="1" icon={<UserOutlined />}>
          <Link to="/app/producttomms">Share Product to MMS</Link>
        </Menu.Item>
        <Menu.Item key="2" icon={<UserOutlined />}>
          <Link to="/app/paymentorderanalyzer">Payment Order Analyzer</Link>
        </Menu.Item>
        <Menu.Item key="3" icon={<UserOutlined />}>
          <Link to="/app/masterdatainitializer">Master Data Initializer</Link>
        </Menu.Item> */}
        {subMenuList}
      </Menu>
    </Sider>
  );
};

export default SideMenuComponent;
提升状态
  • 将你的状态提升到共同祖先(即父母)

  • 由于两者都可以访问该状态,因此可以通过一个子级的回调来更新父级

  • 这反过来会更新另一个子项,因为两个子项共享相同的状态

导出默认函数父函数(){
const[text,setText]=React.useState('尚未更新');
返回(
);
}
函数Child1({text}){
返回{text}

} 函数Child2({onClick}){ return onClick('Child2更新了状态')}>Update }
您可能需要将状态从
WebHeaderComponent
提升到两者最接近的共同祖先,并将一些属性值传递给
SideMenuComponent
,以便它重新呈现。@Drewerese谢谢您的评论,您介意给我举个例子吗。我是一个新的反应,不知道真正需要做什么来实现你的目标。
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application.
export default function Parent() {
  const [text, setText] = React.useState('not yet updated');

  return (
    <div>
      <Child1 text={text} />
      <Child2 onClick={setText} />
    </div>
  );
}

function Child1({ text }) {
  return <p>{text}</p>
}

function Child2({ onClick }) {
  return <button onClick={() => onClick('Child2 updated the state')}>Update</button>
}