【发布时间】:2019-08-21 06:21:56
【问题描述】:
我正在尝试使用 React 16.8.3 构建导航栏。我想使用组合来传递导航栏内容,而不是通过道具传递配置对象,以获得更大的灵活性。像这样的:
<Navbar>
<NavItem>Some label</NavItem>
<NavItem>
<span>Some arbitrary content</span>
<NavItem>
</Navbar>
代替:
const navItems = [
{
label: 'Some label'
},
{
label: 'Some other label'
}
]
<Navbar items={navItems} />
到目前为止,导航栏工作正常。我在 shouldComponentUpdate 方法中添加了一些逻辑来防止多次重新渲染:
shouldComponentUpdate(nextProps) {
return nextProps.selectedItem !== this.props.selectedItem;
}
因此,导航栏仅在其所选项目更改时重新渲染,而不是在导航栏父级重新渲染时。
问题是一个 NavItem 包含一个带有任务计数的标记,每当用户执行某些任务时必须更新该标记:
项目标记是:
<Navbar>
<NavItem>
<div className="has-badge">
<span>Label</span>
<span className="badge">{this.props.toDoCount}</span>
</div>
</NavItem>
</Navbar>
this.props.toDoCount 是导航栏父级的道具,而不是导航栏本身的道具。
如何在不重新渲染整个导航栏的情况下更新徽章编号?到目前为止,我已经尝试创建一个徽章组件,添加一些状态,以及使用导航栏父级中的 ref 更新徽章编号的方法:
import React, { PureComponent } from 'react';
interface BadgeProps {
number: number;
}
class Badge extends PureComponent<BadgeProps> {
state = {
number: 0
};
setCount(number) {
this.setState({
number
});
}
render() {
return <span className="badge">{this.state.number}</span>;
}
}
在导航栏父级中:
private todos = createRef<Badge>();
...
componentDidUpdate(prevProps: EhrProps) {
this.todos.current.setCount(toDosCount);
}
它正在工作,但是......在 React 中是否有更简单或更清洁的方法??
谢谢!
PS:我们在项目中使用 Redux,但我想避免使用 Navbar 中的 store 或其项目。
编辑:
我在导航栏的渲染方法中使用了 React.children 和 React.cloneElement:
render() {
const { className, children, selectedItem, ...rest } = this.props;
const classes = classNames(
{
navbar: true
},
className
);
return (
<nav className={classes} {...rest}>
{React.Children.map(children, child => {
if (child.type === NavItem) {
return React.cloneElement(child, {
onClick: this.handleItemClick,
selected: child.props.name === selectedItem
});
}
return child;
})}
</nav>
);
}
每个 NavItem 处理自己的渲染:
return (
<div className={classes} onClick={handleClick} onKeyPress={handleKeyPress} role="menuitem" tabIndex={0}>
{children}
</div>
);
【问题讨论】:
标签: reactjs