我正在开发一个 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
在这种情况下使用的好处。
谢谢!