在create-react-app脚手架中:【使用React-Redux让代码最优雅的呈现】

和往常一样,本文的所有文件—-仍然是基于 create-react-app脚手架 创建的项目的 ./src/ 文件夹下

react-redux

  • npm install react-redux –save
  • 有了react-redux,就可以忘记 store.subscribe函数了,记住reducer action和dispatch即可。
  • React-redux提供了 Providerconnect两个接口来链接
//在index.js中
//第一步
import { Provider } from 'react-redux';

//第二步
    ReactDOM.render(
        (//还可以通过传递store>
            
                
            
        ),
        document.getElementById('root')
    );
//在app.js中 第三步
import { connect } from 'react-redux';
import { addGun, removeGun,addGunAsync } from './index.redux';
//第四步
const mapStatetoProps= state=>({num: state });
const actionCreators = { addGun, removeGun,addGunAsync };
App = connect(mapStatetoProps, actionCreators)(App);
//然后就可以直接在this.props中使用addGun, removeGun,addGunAsync,num这几个属性了,在下面贴出的源码文件中有明确的代码。

cennect(mapStatetoProps,actionCreators )函数可以用装饰器的方式来书写

  • 由于 需要额外的插件,需要执行 npm run eject ,才能自行配置。
  • npm install babel-plugin-transform-decorators-legacy
  • Package.json 里面的 babel 字段加上plugins配置
  "babel": {
    "presets": [
      "react-app"
    ],
    "plugins": ["transform-decorators-legacy"]
  }

然后就可以用 @connect 的方式来写了,效果可以看下面源码中的效果对比,非常优雅!

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux'; 
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';

import { counter } from './index.redux';
import App from './app';

//store
const store = createStore(counter, applyMiddleware(thunk));

//get inititalState
const init = store.getState();
console.log(init);

//store.subscribe所需的参数为
store.subscribe(render);
function render() {
    ReactDOM.render(
        (
            >
                <App />
            Provider>
        ),
        document.getElementById('root')
    );
}
render();

//每次调用store.dispatch就会触发store.subcribe, 通常store.dispatch放在最后


//app.js
import React from 'react';
import { connect } from 'react-redux';
//引入三个action创建函数,其中有一个是一个dispatch返回一个异步函数,这个异步函数再执行一个dispatch的定时任务
import { addGun, removeGun, addGunAsync } from './index.redux';   

//mapStatetoProps是为connect函数的 第一个 参数而准备的
/* const mapStatetoProps = state=> {
    return { num: state }//将num属性映射到this.props,this.props则拥有了this.props.num属性。
} */

//actionCreators是为connect函数的 第二个 参数而准备的
/* 
const actionCreators = { addGun, removeGun, addGunAsync };
App = connect(mapStatetoProps, actionCreators) (App); 
*/
@connect(//上面6-15行的代码,可以用一个@connect的装饰器来替换,这样代码会更加简洁和优雅
    state=>({num:state}),
    { addGun, removeGun, addGunAsync }
)

class App extends React.Component {
    // constructor(props) {
    //     super(props);
    // }
    render() {
        return (
            

现在有机枪 { this.props.num } 把

   
/*onClick后面的值必须是纯函数的形式,而不能是一段可执行代码*/ ) } } //mapStatetoProps是为connect函数的 第一个 参数而准备的 const mapStatetoProps = state=> { return { num: state }//将num属性映射到this.props,this.props则拥有了this.props.num属性。 } //actionCreators是为connect函数的 第二个 参数而准备的 const actionCreators = { addGun, removeGun, addGunAsync }; App = connect(mapStatetoProps, actionCreators) (App); export default App;
相对于上一篇文章,index.redux.js完全没有修改
//index.redux.js
const addGUN = 'addGUN';
const removeGUN = 'removeGUN';

//reducer
export function counter(state=10, action) {
    switch(action.type) {
        case addGUN: 
        return state+1;
        case removeGUN: 
        return state-1;
        default :
        return state
    }
}

//action创建函数
export function addGun() {
    return { type: addGUN }
}
export function removeGun() {
    return { type: removeGUN }
}
export function addGunAsync() {
    return (dispatch)=>{
        setTimeout(()=>{
            dispatch(addGun())
        },2000)
    }
}

//这个文件仅仅存放了 reducer 和 action创建函数

你可能感兴趣的:(Redux)