npm start == roadhog server
roadhog webpack自动打包和热更替
默认配置entry src/index.js
index.js中
引入dva
通过函数生成一个 app 对象:const app = dva();
加载插件:app.use({});
注入 model:app.model(require('./models/example'));
添加路由:app.router(require('./routes/indexAnother'));
启动:app.start('#root');
是高性能虚拟DOM、服务器端Render、封装过的事件机制、还是完善的错误提示信息?尽管每一点都足以重要。但他指出,其实React最有价值的是声明式的,直观的编程方式。
我们来回顾一下到底发生了什么事情,对于 InputWithUserName 和 TextareaWithContent 这两个组件来说,它们的需求有着这么一个相同的逻辑:“挂载阶段从 LocalStorage 中加载特定字段数据”。
到这里,高阶组件的作用其实不言而喻,其实就是为了组件之间的代码复用。组件可能有着某些相同的逻辑,把这些逻辑抽离出来,放到高阶组件中进行复用。高阶组件内部的包装组件和被包装组件之间通过 props 传递数据。
import React, { Component } from 'react'
export default (WrappedComponent, name) => {
class NewComponent extends Component {
constructor () {
super()
this.state = { data: null }
}
componentWillMount () {
let data = localStorage.getItem(name)
this.setState({ data })
}
render () {
return
}
}
return NewComponent
}
createStore,它可以产生一种我们新定义的数据类型 store,通过 store.getState 我们获取共享状态,而且我们约定只能通过 store.dispatch 修改共享状态。store 也允许我们通过 store.subscribe 监听数据数据状态被修改了,并且进行后续的例如重新渲染页面的操作。
我们从一个简单的例子的代码中发现了共享的状态如果可以被任意修改的话,那么程序的行为将非常不可预料,所以我们提高了修改数据的门槛:你必须通过 dispatch 执行某些允许的修改操作,而且必须大张旗鼓的在 action 里面声明。
这种模式挺好用的,我们就把它抽象出来一个 createStore,它可以产生 store,里面包含 getState 和 dispatch 函数,方便我们使用。
后来发现每次修改数据都需要手动重新渲染非常麻烦,我们希望自动重新渲染视图。所以后来加入了订阅者模式,可以通过 store.subscribe 订阅数据修改事件,每次数据更新的时候自动重新渲染视图。
接下来我们发现了原来的“重新渲染视图”有比较严重的性能问题,我们引入了“共享结构的对象”来帮我们解决问题,这样就可以在每个渲染函数的开头进行简单的判断避免没有被修改过的数据重新渲染。
我们优化了 stateChanger 为 reducer,定义了 reducer 只能是纯函数,功能就是负责初始 state,和根据 state 和 action 计算具有共享结构的新的 state。
createStore 现在可以直接拿来用了,套路就是:
// 定一个 reducer
function reducer (state, action) {
/* 初始化 state 和 switch case */
}
// 生成 store
const store = createStore(reducer)
// 监听数据变化重新渲染页面
store.subscribe(() => renderApp(store.getState()))
// 首次渲染页面
renderApp(store.getState())
// 后面可以随意 dispatch 了,页面自动更新
store.dispatch(...)
现在的代码跟 React.js 一点关系都没有,接下来我们要把 React.js 和 Redux 结合起来,用 Redux 模式帮助管理 React.js 的应用状态。