React和Redux手动链接过程
1.新建store(仓库)
import {createStore} from 'redux'
const store = createStore(reducer)//通过传入reducer建立store
2.以组件属性形式传递给组件里
function render(){
ReactDom.render(<App store={store}/>)
}
render()
3.使用store的subscribe函数订阅render()
store.subscribe(render)
4.组件内部通过props获取store
const store= this.props.store
5.补充一个reducer和action creator的例子
//reducer
export function documents(state=initState,action){
switch(action.type){
case GET_DOCUMENT_SUCCESS:
return {...state,documents:action.documents}
case ERROR_MSG:
return {...state,msg:action.msg}
default:
return state;
}
}
//action creator ==>create reducer action 只要提交action reducer就会执行
export function getDocumentInfo({type}){
//返回函数需要使用thunk
return dispatch=>{
axios.get('asd',{type})
.then(
res=>{
console.log(res);
if(res.state===200){
dispatch(getInfoSuccess(res.data.documents))
}else{
dispatch(errorMsg(res.msg))
}
}
)
.catch(function (error) {
console.log(error);
});
}
更进一步,Redux和React更优雅的结合
1. Redux处理异步使用redux-thunk插件
2. npm install redux-devtools-extension 并且开启
3. 使用react-redux优雅的链接react和redux
1.Redux默认只处理同步,异步任务需要react-thunk中间件
- npm install redux-thunk --save
- 使用applyMiddleware开启thunk中间件
- Action由返回对象增加可以返回函数,这时使用dispatch提交action
import thunk from 'redux-thunk';
import {createStore,applyMiddleware} from 'redux';
const store = createStore(reducers,applyMiddleware(thunk))
2.调试工具
1.Chrome搜索redux插件安装
2.新建store的时候判断window.devToolsExtension
3.使用compose结合thunk和window.devToolsExtension
4.通过调试窗redux选项卡实时看到state
import {createStore,applyMiddleware,compose} from 'redux';
const store = createStore(reducers,compose(
applyMiddleware(thunk),
window.devToolsExtension?window.devToolsExtension():f=>f
))
3.使用react-redux
1.npm install react-redux --save
2.忘记subscribe,记住reducer,action和dispatch即可
3.React-redux 提供Provider和connect两个接口来链接
1.Provider组件在应用最外层,传入store即可,只用一次
import { Provider } from "react-redux";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
2.Connect负责从外部获取组件需要的参数(Connect可以用装饰器来写)
connect方法
connenct并不会改变它“连接”的组件,而是提供一个经过包裹的connect组件。 conenct接受4个参数,分别是mapStateToProps,mapDispatchToProps,mergeProps,options(使用时注意参数位置顺序)。
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
这里只介绍两个必须参数
mapStateToProps(state, ownProps) 方法允许我们将store中的数据作为props绑定到组件中,只要store更新了就会调用mapStateToProps方法,mapStateToProps返回的结果必须是object对象,该对象中的值将会更新到组件中,例子:
const mapStateToProps = (state) => {
return ({
count: state.counter.count
})
}
mapDispatchToProps(dispatch, [ownProps]) 第二个参数允许我们将action作为props绑定到组件中,mapDispatchToProps希望你返回包含对应action的object对象,例如:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
increase: (...args) => dispatch(actions.increase(...args)),
decrease: (...args) => dispatch(actions.decrease(...args))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(yourComponent)
实例:
Class App extends React.Component{
}
const mapStateToProps(state){
return {num:state}
}
const mapDispatchToProps={yourActionCreators}
App = connect(mapStateToProps,mapDispatchToProps)(App)
export default App
使用装饰器优化connect代码
1.npm run eject弹出个性化配饰(针对create-react-app)
2.npm install babel-plugin-transform-decorators-legacy --save
3.package.json 里babel加上plugins配置
3.babel加上plugins配置
"babel": {
"presets": [
"react-app"
],
"plugins":["transform-decorators-legacy"]
},
改变写法为
```
const mapStateToProps(state){return {num:state}}
const mapDispatchToProps={yourActionCreators}
@connect(mapStateToProps,mapDispatchToProps)
Class App extends React.Component{
}
export default App
“`