redux入门
2018-08-17 本文已影响6人
我竟无言以对_1202
什么是redux
redux是一个状态管理工具。react设计理念是单向数据流,而我们在用react构建前端应用的时候,通常需要获取其他组件的状态,如果组件繁多,获取修改其状态就比较麻烦,这时候就用到了redux。
redux使用场景
- 某个组件的状态,需要共享
- 某个状态需要在任何地方都可以拿到
- 一个组件需要改变全局状态
- 一个组件需要改变另一个组件的状态
安装
npm install redux --save
store
store就是保存数据的地方,你可以把它看成一个容器,整个应用只能有一个store。
redux提供createStore这个函数,用来生成store
import {createStore} from 'redux'
// 根据老的state和action生成新的state
function counter(state=0,action){
switch(action.type){
case "+":
return state+1;
case "-":
return state-1;
default:
return 10;
}
}
// 新建store
const store = createStore(counter);
state
- 当前的状态可以通过store.getState()拿到。
import {createStore} from 'redux'
// 根据老的state和action生成新的state
function counter(state=0,action){
switch(action.type){
case "+":
return state+1;
case "-":
return state-1;
default:
return 10;
}
}
// 新建store
const store = createStore(counter)
const state = store.getState();
console.log(state); // 10
- 通过dispatch(action)方法派发事件更新state
import {createStore} from 'redux'
// 根据老的state和action生成新的state
function counter(state=0,action){
switch(action.type){
case "+":
return state+1;
case "-":
return state-1;
default:
return 10;
}
}
// 新建store
const store = createStore(counter)
console.log(store.getState()); //10
// 派发事件
store.dispatch({type:'+'})
console.log(store.getState()); // 11
- 通过store.subscribe()注册监听器,监听state变化
import {createStore} from 'redux'
// 根据老的state和action生成新的state
function counter(state=0,action){
switch(action.type){
case "+":
return state+1;
case "-":
return state-1;
default:
return 10;
}
}
// 新建store
const store = createStore(counter)
function listener(){
const current = store.getState();
console.log(`现在数字是${current}`);
}
store.subscribe(listener);
store.dispatch({type:'+'})
- 解除监听
store.subscribe方法返回一个函数,调用这个函数就可以解除监听。
let unsubscribe = store.subscribe(() =>
console.log(store.getState())
);
unsubscribe();
action
action是一个对象,其中的type属性是必须的,表示action的名称。
const action = {
type:'+'
}
action并不止type这一个参数,其他参数看自己情况添加,这里不一一叙述。
Action Creator
要发送多少种消息,就会有多少种 Action。如果都手写,会很麻烦。可以定义一个函数来生成 Action,这个函数就叫 Action Creator
const ADD_TODO = '添加 TODO';
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
const action = addTodo('Learn Redux');
reducer
state收到action后,必须给出一个state,这样view才会发生变化,这种state的计算过程就是reducer。就是上面咱们用到的
function counter(state=0,action){
switch(action.type){
case "+":
return state+1;
case "-":
return state-1;
default:
return 10;
}
}
当遇到多个reducer时,需要用{combineReducers}合并
import {combineReducers} from 'redux'
import {counter} from './index.redux'
import {auth} from './Auth.redux'
export default combineReducers({counter,auth})
以上就是redux的基本用法,但是都是同步的,当我们遇到不要异步操作怎么办?这时候就需要用到中间件(middleware)
异步任务需要react-thunk中间件
npm install redux-thunk --save
import { createStore ,applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
const store = createStore(counter,applyMiddleware(thunk));
// 异步函数,使用redux-thunk中间件改造store.dispatch
function addAsync(){
return dispatch=>{
setTimeout(()=>{
dispatch(add);
},2000)
}
}
react-redux
安装
npm install react-redux --save
react-redux将所有组件分成两大类:ui组件和容器组件
ui组件
ui组件有以下几个特征
- 只负责ui的呈现,不带任何业务逻辑
- 没有状态(即不使用this.state这个变量)
- 所有数据都由参数(this.props)提供
- 不使用任何redux的api
容器组件
容器组件有以下几个特征
- 负责管理数据和业务逻辑,不负责 UI 的呈现
- 带有内部状态
- 使用 Redux 的 API
provider()
provider组件在应用最外层,传入store即可,只用一次
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
import { createStore ,applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {counter} from './index.redux'
import {Provider} from 'react-redux'
const store = createStore(counter,applyMiddleware(thunk));
ReactDom.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
connect()
connect负责从外部获取组件需要的参数
import React from 'react'
import {connect} from 'react-redux'
import {add,sub,addAsync} from './index.redux'
class App extends React.Component{
render(){
return (
<div>
<h1>现在数字:{this.props.num}</h1>
<button onClick={this.props.add}>+1</button>
<button onClick={this.props.sub}>-1</button>
<button onClick={this.props.addAsync}>异步+1</button>
</div>
)
}
}
// state对象
const mapStatetoProps = (state)=>{
return {num:state}
}
// store.dispatch方法的映射
const actionCreators = {add,sub,addAsync}
App = connect(mapStatetoProps,actionCreators)(App)
export default App