1.安裝
npm install --save redux
Redux Dev Tools // 調(diào)試工具 谷歌擴展插件 科學上網(wǎng)
2.創(chuàng)建一個store文件夾在文件夾下創(chuàng)建一個index.js文件
import { createStore } from 'redux' // 引入createStore方法
const store = createStore() // 創(chuàng)建數(shù)據(jù)存儲倉庫
export default store //暴露出去
3.在store文件夾下,新建一個文件reducer.js
const defaultState = {
inputValue: '默認',
List: [
'數(shù)據(jù)1',
]
} //默認數(shù)據(jù)
//就是一個方法函數(shù)
export default (state = defaultState,action)=>{
return state
}
4. reducer引入到store中
import { createStore } from 'redux' // 引入createStore方法
import reducer from './reducer'
const store = createStore(reducer) // 創(chuàng)建數(shù)據(jù)存儲倉庫
export default store //暴露出去
5.獲得stroe中的數(shù)據(jù)
import store from './store/index'//引入store
constructor(props){ //初始化賦值使用
super(props)
this.state=store.getState();
console.log(this.state)
}
</div>{this.state.inputValue} <div> //得到 ‘默認’
6. 修改Redux里State的值
1.創(chuàng)建Action;type:事件類型 value:參數(shù)
inputChange(e){
const action ={
type:'change_input_value',
value:e.target.value
}
store.dispatch(action)
}
// 通過dispatch()方法傳遞給store
2. Reducer處理數(shù)據(jù)
export default (state = defaultState,action)=>{
if(action.type === 'changeInput'){ //判斷類型
let newState = JSON.parse(JSON.stringify(state))//深度拷貝state
newState.inputValue = action.value
return newState
}
if (action.type === 'changeList') {//添加數(shù)組一項
if (state.inputValue !== '') {
let newState = JSON.parse(JSON.stringify(state))
newState.List.push(newState.inputValue)
newState.inputValue = ''
return newState
}
}
return state
}
3訂閱更新
//回到頁面訂閱Redux的狀態(tài)
constructor(props){
super(props)
store.subscribe(this.storeChange) //訂閱Redux的狀態(tài)
}
storeChange(){
this.setState(store.getState())
}
7. 優(yōu)雅的管理action.type
1. src/store文件夾下面,新建立一個actionTypes.js文件
2. 提取type統(tǒng)一管理
const ActionsType = {
CHANGE_INPUT: 'changeInput', //文本框改變
CHANGE_LIST: 'changeList', //數(shù)組改變
DEL_LIST: 'delList', //刪除數(shù)組
}
export default ActionsType
3. 頁面引入actionTypes使用
import ActionsType from './store/actionTypes'
const action = {
type: ActionsType.CHANGE_INPUT,
value: e.target.value
}
4.引入actionType.js文件
if (action.type === ActionsType.CHANGE_INPUT) {
let newState = JSON.parse(JSON.stringify(state))
newState.inputValue = action.value
return newState
}
if (action.type === ActionsType.CHANGE_LIST) {
if (state.inputValue !== '') {
let newState = JSON.parse(JSON.stringify(state))
newState.List.push(newState.inputValue)
newState.inputValue = ''
return newState
}
}
8.優(yōu)雅的管理Action
1. 在/src/store文件夾下面,建立一個新的文件actionCreates.js
2. 提取action
import ActionsType from './actionTypes'
//輸入框改變
export const changeInputAction = (value) => ({
type: ActionsType.CHANGE_INPUT,
value: value
})
//數(shù)組添加
export const changeListAction = () => ({
type: ActionsType.CHANGE_LIST,
})
//數(shù)組刪除
export const delListAction = (value) => ({
type: ActionsType.DEL_LIST,
value: value
})
3.引入actionCreates.js使用
import { changeInputAction, changeListAction, delListAction } from './store/actionCreates'
//使用changeInputAction
const action = changeInputAction(e.target.value)
store.dispatch(action)
//使用changeListAction
const action = changeListAction()
store.dispatch(action)
//使用delListAction
const action = delListAction(index)
store.dispatch(action)
9.無狀態(tài)組件
// 無狀態(tài)組件
const TodoListUi = (props) => {
return (
<div>
<Input
placeholder={props.inputValue}
value={props.inputValue}
style={{ width: '200px' }}
onChange={props.changeInputValue}
/>
<Button onClick={props.chlickBtn} > 添加 </Button>
<div style={{ width: '200px' }}>
<List
bordered
dataSource={props.List}
renderItem={(item, index) => (
<List.Item onClick={() => { props.chlickBtnList(index) }} >
{item}
</List.Item>
)
}
/>
</div>
</div>
)
}
export default TodoListUi;
// 使用
<TodoListUi
inputValue={this.state.inputValue}
List={this.state.List}
changeInputValue={this.changeInputValue}
chlickBtn={this.chlickBtn}
chlickBtnList={this.chlickBtnList}
/>
10. Redux-thunk中間件
1.安裝
npm install --save redux-thunk
2.在 store下的index.js文件里添加thunk
寫法1:
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import thunk from 'redux-thunk'
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose//寫法1
const enhancer = composeEnhancers(applyMiddleware(thunk))//寫法1
const store = createStore(
reducer,
enhancer//寫法1
);
export default store
寫法2
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import thunk from 'redux-thunk'
// 用于chrome redux的擴展項 //寫法2
const reduxExtension = window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__();
const store = createStore(
reducer,
compose(applyMiddleware(thunk), reduxExtension) //寫法2
);
export default store
3使用 thunk
以前actionCreators.js都是定義好的action,根本沒辦法寫業(yè)務(wù)邏輯,有了Redux-thunk之后,可以把TodoList.js中的componentDidMount業(yè)務(wù)邏輯放到這里來編寫。也就是把向后臺請求數(shù)據(jù)的代碼放到actionCreators.js文件里。那我們需要引入axios,并寫一個新的函數(shù)方法。(以前的action是對象,現(xiàn)在的action可以是函數(shù)了,這就是redux-thunk帶來的好處)
示例:
1.actionTypes.js中 添加新類型
const ActionsType = {
CHANGE_INPUT: 'changeInput', //文本框改變
CHANGE_LIST: 'changeList', //數(shù)組改變
DEL_LIST: 'delList', //刪除數(shù)組
+ GET_LIST: 'getList',//獲取數(shù)據(jù)
}
2.reducer.js中添加修改數(shù)據(jù)方法
if (action.type === ActionsType.GET_LIST) {
let newState = JSON.parse(JSON.stringify(state))
newState.List = action.value
return newState
}
3.actionCreators.js添加下面方法
//數(shù)據(jù)渲染
export const getListAction = (value) => ({
type: ActionsType.GET_LIST,
value: value
})
//異步數(shù)據(jù)添加
export const getToList = () => {
return (dispatch) => { //支持傳遞一個dispatch
setTimeout(function () {
console.log('123');
const data = ['延時2秒', 'res.data', '獲取數(shù)據(jù)']
const action = getListAction(data) //直接調(diào)用上面聲明的方法
dispatch(action);
}, 2000); //這里2000代表兩秒
}
}
4.TodoList.js中的componentDidMount使用
import {changeInputAction, changeListAction, delListAction, getToList } from './store/actionCreates'
.....
componentDidMount() {
const action = getToList()
store.dispatch(action);
}