我应该使用React State进行用户交互(切换可见性类)吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我应该使用React State进行用户交互(切换可见性类)吗?相关的知识,希望对你有一定的参考价值。
我正在开发一个UI库,我的一些组件根据用户的一些交互来改变他们的“状态”。
例如,用户点击手风琴面板的标题会导致手风琴面板打开并变为可见。通过将visible
修饰符添加到手风琴面板来实现此状态,如下所示:
<div class="accordion">
<div class="accordion_panel-visible">
<div class="accordion_title">foo</div>
<div class="accordion_content">bar</div>
</div>
<div class="accordion_panel">
<div class="accordion_title">fizz</div>
<div class="accordion_content">buzz</div>
</div>
</div>
我之前的假设是React State应该用于根据一些后端数据重新渲染组件。但是,基于查看来自其他UI库等的源代码,它们似乎也在处理具有React State的UI状态。
所以使用React,我可以通过使用原始DOM API实现我想要的东西(如这里的例子所示 - https://reactjs.org/docs/refs-and-the-dom.html):
Accordion.defaultProps = {
name: 'accordion'
};
class Accordion extends React.Component {
toggle(event) {
const panel = event.target.closest('[data-component="panel"]');
const operator = panel.modifier('active') ? 'unset' : 'set';
panel.modifier('active', operator);
}
render() {
return (
<Module {...this.props}>
{this.props.panels.map(({ title, content }, index) => (
<Component name='panel' key={index}>
<Component name='title' onClick={this.toggle}>{title}</Component>
<Component name='content'>{content}</Component>
</Component>
))}
</Module>
)
}
}
这一切都很好 - 但我实际上是在一个React组件中进行DOM操作,我应该避免使用它。在这种情况下,我应该使用React State和Refs(而不是直接的DOM操作)。为了实现上述相同的目的,我相信我能做到:
Accordion.defaultProps = {
name: 'accordion'
};
class Accordion extends React.Component {
constructor(props) {
super(props);
this.panels = [];
this.state = { activePanel: null };
}
toggle(index) {
this.setState({
activePanel: (this.panels[index] === this.state.activePanel) ? null : this.panels[index]
});
}
isActive(index) {
return (this.panels[index] === this.state.activePanel) ? true : false;
}
render() {
return (
<Module {...this.props}>
{this.props.panels.map(({ title, content }, index) => (
<Component name='panel'
key={index}
ref={ref => this.panels[index] = ref}
modifiers={this.isActive(index) ? 'active' : false}
>
<Component name='title' onClick={this.toggle.bind(this, index)}>
{title}
</Component>
<Component name='content'>{content}</Component>
</Component>
))}
</Module>
)
}
}
(我知道上面代码片段的行为会关闭兄弟面板,而第一个片段不是这种情况,但这是微不足道的,可以忽略)。
所以我的问题是,我是否应该利用React State(即后一个例子)?
感觉就好像我的应用程序基于用户交互显示/隐藏/打开/关闭UI元素,这些用户交互不需要/修改/发布/更新/获取/接收数据,然后React实际上不应该关心它们。
但最重要的是 - 这取决于偏好吗?我应该决定React是否应该关心这个问题吗?在一天结束时,react是一个工具,我目前用于在后端自由环境中创建和呈现UI组件的工具。我现在真的很困惑,并且不确定我是否能真正看到在这种情况下使用state
的好处。
谢谢!
正如我理解您的担忧,您只想将后端/通信和业务逻辑放入“React状态”。但正如你自己指出的那样,还有与UI元素相关的状态。手风琴被关闭/打开等。
可以将其分为两类:
- UI State (only for representation purposes)
- Business Logic state
您可以将React的组件状态用于两者。
在构建或使用UI组件库时,为了进行封装,通常会在这些库中保留/管理状态。对于复杂的应用程序,我建议使用一些更强大的状态管理,如react-redux。但也存在人们使用react-redux进行UI和业务逻辑状态的情况。
从可重用性的角度来看,我建议让UI组件不知道实际的应用程序用例(如Accordion,FancyButton,Snackbar等)。另一个组件集合,包括整个页面或其中的一部分(页眉,页脚,导航,MainView等)。
然后 - 当使用redux时 - 你可以拥有所谓的容器,它将组件与redux的存储/状态管理连接起来。
在任何情况下,都应该避免使用refs进行“简单”状态修改。通常这只是必需的,如果你包括第三方库(jQuery之类)或WebComponents/Custom Elements,因为它们可能不能很好地与React道具等开箱即用。
关于评论中的问题:具有呈现FrequentlyAskedQuestions(FAQ)的任务,组件可能如下所示:
应用程序相关的UI组件(“愚蠢”),. / component /FAQ.js:
const FAQ = ({faqs}) => (
<Accordion>
{faqs.map(faq => (
<AccordionPane title={faq.title} content={faq.text} />
))}
</Accordion>
)
并且 - 使用redux - 相应的Container,./ container /FAQ.js:
import {connect} from 'react-redux'
import FAQ from './FAQ'
const mapStateToProps = state => state.faqs
export default connect(mapStateToProps)(FAQ)
以上是关于我应该使用React State进行用户交互(切换可见性类)吗?的主要内容,如果未能解决你的问题,请参考以下文章