Showing/hiding React 组件不维护内部状态

Showing/hiding React components does not maintain internal state

我正在尝试 hide/show React 中基于某些状态的组件。我面临的主要问题是在隐藏和显示期间保持组件的内部状态。下面是执行我期望的代码并维护每个组件(非洲、欧洲、美洲、亚洲)的状态:

render() {
    const {selectedTab} = this.state;
    return (
        <div>
            <div className={selectedTab === 'africa' ? '' : 'hidden-tab'}><Africa /></div>
            <div className={selectedTab === 'europe' ? '' : 'hidden-tab'}><Europe /></div>
            <div className={selectedTab === 'america' ? '' : 'hidden-tab'}><America /></div>
            <div className={selectedTab === 'asia' ? '' : 'hidden-tab'}><Asia /></div>
        </div>
    )
}


//regions.scss
.hidden-tab {
   display: none
}

但是,我对上面代码的整洁度不满意,想重构,这是我面临的问题。这就是我所做的:

render() {
    const {selectedTab} = this.state;
    const tabToRegionMap = {
        'africa': <Africa />,
        'eruope': <Europe />,
        'america': <America />,
        'asia': <Asia />
    };
    const {[selectedTab]: selectedRegion, ...regionsToHide} = tabToRegionMap;

    return (
        <div>
            <div className={'hidden-tab'}>
                {Object.values(regionsToHide)}
            </div>
            {selectedRegion}
        </div>
    );

以上尝试 show/hide 组件,但在 hiding/showing 期间不维护组件的内部状态 - 似乎它们每次都被卸载和重新安装。

谁能帮我解决问题或提出更好的解决方法?那将不胜感激。

PS 我不想将状态移动到父级或 Redux,因为涉及到很多样板文件并且各个组件的状态非常复杂。

如果我理解你的问题,你实际上是在寻找一种方法来清理代码 保持子组件的安装。

所提出的解决方案的问题在于,每次呈现并应该隐藏选项卡时,它都会重新创建元素。它们在渲染到 <div className={'hidden-tab'}> 和不渲染之间切换,每次选定的选项卡更新时都会重新安装。

我建议将 div 元素抽象为一个新组件,该组件有条件地应用 'hidden-tab' 类名。

const Tab = ({ children, selectedTab, tab }) => (
  <div className={selectedTab === tab ? '' : 'hidden-tab'}>
    {children}
  </div>
);

...

render() {
  const {selectedTab} = this.state;
  return (
    <div>
      <Tab selectedTab={selectedTab} tab='africa'><Africa /></Tab>
      <Tab selectedTab={selectedTab} tab='europe'><Europe /></Tab>
      <Tab selectedTab={selectedTab} tab='america'><America /></Tab>
      <Tab selectedTab={selectedTab} tab='asia'><Asia /></Tab>
    </div>
  )
}

如果您想更进一步,您还可以将这些选项卡的包装 div 抽象到一个容器组件中,该组件存储所选选项卡并通过上下文 API 所以 selectedTab 不需要显式传递给每个。

示例:

import { createContext, useContext } from "react";

const TabContext = createContext({
  selectedTab: null
});

const useSelectedTab = () => useContext(TabContext);

const Tabs = ({ children, selectedTab }) => (
  <TabContext.Provider value={{ selectedTab }}>{children}</TabContext.Provider>
);

const Tab = ({ children, tab }) => {
  const { selectedTab } = useSelectedTab();
  return (
    <div className={selectedTab === tab ? "" : "hidden-tab"}>{children}</div>
  );
};

用法:

render() {
  const {selectedTab} = this.state;
  return (
    <Tabs selectedTab={selectedTab}>
      <Tab tab='africa'><Africa /></Tab>
      <Tab tab='europe'><Europe /></Tab>
      <Tab tab='america'><America /></Tab>
      <Tab tab='asia'><Asia /></Tab>
    </div>
  )
}