我正在为一家法国公司开发 HTMl5 视频播放器。我们使用 React 和 Redux 来构建 UI,效果非常好,编写代码非常愉快!我们目前使用eslint-plugin-react来检查 React 代码风格。自上一个版本以来,linter 建议使用纯函数而不是 React 组件(查看规则),但这在我的团队中引发了一些争论。
我们已经将纯函数用于渲染总是相同的东西的非常小的组件(对于给定的道具)。没有问题。但是对于更大的组件,在我看来,纯函数似乎使代码不那么优雅(与其他组件相比也不那么统一)。
这是我们应该更改的组件之一的示例:
const ControlBar = ({ actions, core, root }) => {
const onFullscreenScreen = (isFullscreen) => {
const playerRoot = root;
if (isFullscreen && !screenfull.isFullscreen) {
screenfull.request(playerRoot);
} else {
screenfull.exit();
}
};
const renderIconButton = (glyph, action, label = false) => {
let content = (
<Button modifier="icon" clickCallback={ action }>
<Icon glyph={ glyph } />
</Button>
);
if (label) {
content = <TooltipOrigin content={label}>{content}</TooltipOrigin>;
}
return content;
};
const renderPlayButton = () => {
const { play, pause } = actions;
const { playerState } = core;
if (playerState === CoreStates.PAUSED) {
return renderIconButton(playGlyph, play, 'lecture');
}
return renderIconButton(pauseGlyph, pause, 'pause');
};
const renderMuteButton = () => {
const { mute, unmute } = actions;
const { currentVolume } = core;
if (currentVolume === 0) {
return renderIconButton(muteGlyph, unmute);
}
return renderIconButton(volumeGlyph, mute);
};
const renderFullscreenButton = () => {
const { isFullscreen } = core;
if (!isFullscreen) {
return renderIconButton(fullscreenGlyph, () => { onFullscreenScreen(true); });
}
return renderIconButton(fullscreenExitGlyph, () => { onFullscreenScreen(false); });
};
const { setCurrentVolume } = actions;
const { currentVolume } = core;
return (
<div className={ style.ControlBar }>
<div className={ style.audio }>
{ renderMuteButton() }
<SoundBar setCurrentVolume={ setCurrentVolume } volume={ currentVolume } />
</div>
<div className={ style.controls }>
{ renderPlayButton() }
</div>
<div className={ style.settings }>
{ renderFullscreenButton() }
</div>
</div>
);
};
ControlBar.propTypes = {
actions: PropTypes.object.isRequired,
core: PropTypes.object.isRequired,
root: PropTypes.object.isRequired,
};
export default ControlBar;
相对 :
export default class ControlBar extends Component {
static propTypes = {
actions: PropTypes.object.isRequired,
core: PropTypes.object.isRequired,
root: PropTypes.object.isRequired,
};
onFullscreenScreen(isFullscreen) {
const playerRoot = this.props.root;
if (isFullscreen && !screenfull.isFullscreen) {
screenfull.request(playerRoot);
} else {
screenfull.exit();
}
}
renderIconButton(glyph, action, label = false) {
let content = (
<Button modifier="icon" clickCallback={ action }>
<Icon glyph={ glyph } />
</Button>
);
if (label) {
content = <TooltipOrigin content={label}>{content}</TooltipOrigin>;
}
return content;
}
renderPlayButton() {
const { play, pause } = this.props.actions;
const { playerState } = this.props.core;
if (playerState === CoreStates.PAUSED) {
return this.renderIconButton(playGlyph, play, 'lecture');
}
return this.renderIconButton(pauseGlyph, pause, 'pause');
}
renderMuteButton() {
const { mute, unmute } = this.props.actions;
const { currentVolume } = this.props.core;
if (currentVolume === 0) {
return this.renderIconButton(muteGlyph, unmute);
}
return this.renderIconButton(volumeGlyph, mute);
}
renderFullscreenButton() {
const { isFullscreen } = this.props.core;
if (!isFullscreen) {
return this.renderIconButton(fullscreenGlyph, () => { this.onFullscreenScreen(true); });
}
return this.renderIconButton(fullscreenExitGlyph, () => { this.onFullscreenScreen(false); });
}
render() {
const { setCurrentVolume } = this.props.actions;
const { currentVolume } = this.props.core;
return (
<div className={ style.ControlBar }>
<div className={ style.audio }>
{ this.renderMuteButton() }
<SoundBar setCurrentVolume={ setCurrentVolume } volume={ currentVolume } />
</div>
<div className={ style.controls }>
{ this.renderPlayButton() }
</div>
<div className={ style.settings }>
{ this.renderFullscreenButton() }
</div>
</div>
);
}
}
我们喜欢 React 组件的结构。由于 ES7,PropTypes 和默认 props 可以在类中,这在纯函数中是不可能的。而且,特别是在这个例子中,我们有很多函数来渲染子组件。
如果我们不喜欢,我们可以简单地禁用此规则,但我们真的很想了解这一点,并且我们关心性能和 React 的良好实践。所以,也许你可以帮助我们。
你怎么能帮助我?关于这个有趣的问题,我会得到其他意见。支持纯函数的论据是什么?也许解决方案不是在纯函数中更改 ControlBar 组件,而只是对其进行改进。在这种情况下,您对此有何建议?
非常感谢你的帮助 !