而现在我们知道,这些逻辑是应该放在 Smart 组件里面的:

了解 MVC、MVP 架构模式的同学应该可以类比过去,Dumb 组件就是 View(负责渲染),Smart 组件就是 Controller(Presenter),State 其实就有点类似 Model。其实不能完全类比过去,它们还是有不少差别的。但是本质上兜兜转转还是把东西分成了三层,所以说前端很喜欢炒别人早就玩烂的概念,这话果然不假。废话不多说,我们现在就把这些应用逻辑抽离到 Smart 组件里面。

对于 CommentList 组件,可以看到它接受两个参数:commentsonDeleteComment。说明需要一个 Smart 组件来负责把 comments 数据传给它,并且还得响应它删除评论的请求。我们新建一个 Smart 组件 src/containers/CommentList.js 来干这些事情:

代码有点长,大家通过注释应该了解这个组件的基本逻辑。有一点要额外说明的是,我们一开始传给 CommentListContainerprops.comments 其实是 reducer 里面初始化的空的 comments 数组,因为还没有从 LocalStorage 里面取数据。

因为 dispatch 了导致 connect 里面的 Connect 包装组件去 state 里面取最新的 comments 然后重新渲染,这时候 CommentListContainer 才获得了有数据的 props.comments

这里的逻辑有点绕,大家可以回顾一下我们之前实现的 react-redux.js 来体会一下。

对于 CommentInput 组件,我们可以看到它有三个参数:usernameonSubmit、。我们需要一个 Smart 的组件来管理用户名在 LocalStorage 的加载、保存;用户还可能点击“发布”按钮,所以还需要处理评论发布的逻辑。我们新建一个 Smart 组件 src/containers/CommentInput.js 来干这些事情:

同样地,对代码的解释都放在了注释当中。这样就构建了一个 Smart 的 CommentInput

接下来的事情都是很简单,我们用 CommentApp 把这两个 Smart 的组件组合起来,把 src/CommentApp.js 移动到 src/containers/CommentApp.js,把里面的内容替换为:

最后一步,修改 src/index.js

通过 commentsReducer 构建一个 store,然后让 Provider 把它传递下去,这样我们就完成了最后的重构。

我们最后的组件树是这样的:

文件目录:


因为第三方评论工具有问题,对本章节有任何疑问的朋友可以移步到 React.js 小书的论坛 发帖,我会回答大家的疑问。