Redux Example
Examples from http://redux.js.org/docs/introduction/Examples.html
Counter Vanilla
Run the Counter Vanilla example:
git clone https://github.com/reactjs/redux.git
cd redux/examples/counter-vanilla
open index.html
index.html
<!DOCTYPE html>
<html>
<head>
<title>Redux basic example</title>
<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>
</head>
<body>
<div>
<p>
Clicked: <span id="value">0</span> times
<button id="increment">+</button>
<button id="decrement">-</button>
<button id="incrementIfOdd">Increment if odd</button>
<button id="incrementAsync">Increment async</button>
</p>
</div>
<script>
function counter(state, action) {
if (typeof state === 'undefined') {
return 0
}
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
var store = Redux.createStore(counter)
var valueEl = document.getElementById('value')
function render() {
valueEl.innerHTML = store.getState().toString()
}
render()
store.subscribe(render)
document.getElementById('increment')
.addEventListener('click', function () {
store.dispatch({ type: 'INCREMENT' })
})
document.getElementById('decrement')
.addEventListener('click', function () {
store.dispatch({ type: 'DECREMENT' })
})
document.getElementById('incrementIfOdd')
.addEventListener('click', function () {
if (store.getState() % 2 !== 0) {
store.dispatch({ type: 'INCREMENT' })
}
})
document.getElementById('incrementAsync')
.addEventListener('click', function () {
setTimeout(function () {
store.dispatch({ type: 'INCREMENT' })
}, 1000)
})
</script>
</body>
</html>
分析:
function counter(state, action) {....}
作为一个函数,通过var store = Redux.createStore(counter)
变成了一个 store。
这个 store的两个参数可以通过store.getState()
和 store.dispatch({ type: 'INCREMENT' })
使用,返回值皆为 state。
store.subscribe(callbackFunc)
这个函数用于监听 state的变化,并调用 callbackFunc
.
其中 dispatch 函数还可以进行异步调用:
setTimeout(function () {
store.dispatch({ type: 'INCREMENT' })
}, 1000)
Counter
Run the Counter example:
git clone https://github.com/reactjs/redux.git
cd redux/examples/counter
npm install
npm start
open http://localhost:3000/
项目结构
reducers 中 store 函数
export default (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
index.js 中通过 prop传递 store
const render = () => ReactDOM.render(
<Counter
value={store.getState()}
onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
/>,
rootEl
)
Todos
Run the Todos example:
git clone https://github.com/reactjs/redux.git
cd redux/examples/todos
npm install
npm start
open http://localhost:3000/
项目结构
这个例子中 store 不再是一个组件组成,而是由多个组件混合。并且 store中对 action的操作不再仅仅是判断 action.type,还可以获取更多的 action属性。
使用 react-redux
的 Provider 创建一个带有 store的容器
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import reducer from './reducers'
const store = createStore(reducer)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
而 App 组件是由3个组件构成
const App = () => (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
)
其中一个组件,调用 dispatch 传递 action函数作为参数。 而通过react-redux
的 connect 组件将其关联到 store上。
import { connect } from 'react-redux'
import { addTodo } from '../actions'
let AddTodo = ({ dispatch }) => {
let input
return (
<div>
<form onSubmit={e => {
e.preventDefault()
if (!input.value.trim()) {
return
}
dispatch(addTodo(input.value))
input.value = ''
}}>
<input ref={node => {
input = node
}} />
<button type="submit">
Add Todo
</button>
</form>
</div>
)
}
AddTodo = connect()(AddTodo)
TodoMVC
Run the TodoMVC example:
git clone https://github.com/reactjs/redux.git
cd redux/examples/todomvc
npm install
npm start
open http://localhost:3000/
项目结构
这个项目跟上个项目并无大致,只不过多了一个 constants。它的作用主要是把字符串变成常量。
Shopping Cart
Run the Shopping Cart example:
git clone https://github.com/reactjs/redux.git
cd redux/examples/shopping-cart
npm install
npm start
open http://localhost:3000/
项目结构
使用了 redux-chuck 作中间层,redux-logger 作日志。
import React from 'react'
import { render } from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import { createLogger } from 'redux-logger'
import thunk from 'redux-thunk'
import reducer from './reducers'
import { getAllProducts } from './actions'
import App from './containers/App'
const middleware = [ thunk ];
if (process.env.NODE_ENV !== 'production') {
middleware.push(createLogger());
}
const store = createStore(
reducer,
applyMiddleware(...middleware)
)
store.dispatch(getAllProducts())
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
Tree view
Run the Tree View example:
git clone https://github.com/reactjs/redux.git
cd redux/examples/tree-view
npm install
npm start
open http://localhost:3000/