显示/隐藏 React 组件不会保持内部状态
Posted
技术标签:
【中文标题】显示/隐藏 React 组件不会保持内部状态【英文标题】:Showing/hiding React components does not maintain internal state 【发布时间】:2021-12-31 13:50:27 【问题描述】:我正在尝试根据某些状态在 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>
);
上述尝试确实显示/隐藏了组件,但在隐藏/显示期间不保持组件的内部状态 - 似乎每次都在卸载和重新安装它们。
谁能帮我解决问题或提出更好的解决方法?那将不胜感激。
PS 我不希望将状态移动到父级或 Redux,因为这涉及到很多样板,并且各个组件的状态非常复杂。
【问题讨论】:
【参考方案1】:如果我理解您的问题,您实际上是在寻找一种清理代码的方法并保持子组件的安装。
建议的解决方案的问题是,每次渲染并隐藏选项卡时,它都会重新创建元素。它们在渲染到<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>
)
【讨论】:
感谢您的建议@DrewReese!我尝试使用第一个按预期显示/隐藏的解决方案。但是,内部状态仍未维持。知道为什么会这样吗? @John 您有这些国家/地区组成部分之一的示例以及您希望它们维持的那种状态吗?如果它们保持安装状态,那么我不明白为什么即使隐藏状态也不会保持状态。我将在我链接的 CSB 中进行测试。 这里很难粘贴,因为它们是非常复杂的组件,使用我们内部 React 框架中的组件作为主要组件。也许这与我从框架中提取的那些组件有关。 我尝试将新组件放在类方法和 render() 中。这是我要去错的地方吗?像这样:``` buildTabContent() const Tab = ( children, selectedTab, tab ) => ( children ); render() return this.buildTabContent(); ``` @John 这是我的 CSB 的 fork,我在其中为每个Country
组件添加了一些基本状态,由每个渲染的组件独立更新,甚至将 display: none;
应用于隐藏的组件和它们保持其内部状态。当然,CSB 是我建议的第二个实现,但它实际上只是为您抽象出活动选项卡值。如果没有看到您的更新版本,很难说为什么您的组件没有保持安装状态。以上是关于显示/隐藏 React 组件不会保持内部状态的主要内容,如果未能解决你的问题,请参考以下文章
在 react-native 中显示/隐藏状态更改的组件时出错
如何使用 React-Bootstrap 和 Redux 显示/隐藏 Modal?
Swift iOS - 即使我隐藏它,导航栏也不会保持隐藏状态