本文内容来自 Facebook 官方Git Repo: counter
它所讲述的内容,是把 counter-vanilla中的例子和React结合在一起。
效果:
项目的目录结构:
- components
- Counter.js
- Counter.spec.js
- reducers
- index.js
- index.spec.js
- index.js
这个项目是通过create-react-app创建的,因此,它的入口就是最外层的index.js
:
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import Counter from './components/Counter'
import counter from './reducers'
const store = createStore(counter)
const rootEl = document.getElementById('root')
const render = () => ReactDOM.render(
<Counter
value={store.getState()}
onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
/>,
rootEl
)
render()
store.subscribe(render)
从这个文件的内容,可以看出它和普通的react文件的index有一些差别:
1. 它创建了一个store,const store = createStore(counter)
;
2. 建立订阅关系,store.subscribe(render)
,之后,就可以在render
里面使用store
来获得状态和发起dispathch
。
从这个index.js
中,引入了两个COUNTER:
import Counter from './components/Counter'
import counter from './reducers'
第一个Counter
是一个标准的react构件,内容就是把 counter-vanilla 翻译成react版本:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
class Counter extends Component {
constructor(props) {
super(props);
this.incrementAsync = this.incrementAsync.bind(this);
this.incrementIfOdd = this.incrementIfOdd.bind(this);
}
incrementIfOdd() {
if (this.props.value % 2 !== 0) {
this.props.onIncrement()
}
}
incrementAsync() {
setTimeout(this.props.onIncrement, 1000)
}
render() {
const { value, onIncrement, onDecrement } = this.props
return (
<p>
Clicked: {value} times
{' '}
<button onClick={onIncrement}>
+
</button>
{' '}
<button onClick={onDecrement}>
-
</button>
{' '}
<button onClick={this.incrementIfOdd}>
Increment if odd
</button>
{' '}
<button onClick={this.incrementAsync}>
Increment async
</button>
</p>
)
}
}
Counter.propTypes = {
value: PropTypes.number.isRequired,
onIncrement: PropTypes.func.isRequired,
onDecrement: PropTypes.func.isRequired
}
export default Counter
第二个counter
则对应的是reducer目录下面的index.js中的内容。一目了然:
export default (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
要想在线观看显示效果,可以直接到 codesandbox - counter