Redux实践,简单易懂好上手

352 阅读3分钟

一、安装依赖

笔者版本: react版本 17.0.2 redux 4.0.5

虽然react也可以使用npm, 但是react官方主要是使用yarn管理包的,推荐大家也可以了解下,学习成本不高

yarn add redux

笔者的redux实践可以和常规的有些不同,先列出文件结构,后面会说明原因。

image.png

二、创建reducers

这里的store就是redux实际应用的文件了,和Vuex的状态管理文件创建的文件夹是store是意义的

课外小知识: store本意也有存储的意思,所以语义化更强[点赞]

redux在reduce人中可以单独创建数据存储对象,所以并不是一定需要通过state.js文件

// /store/reducers/mainReducer.js
import {combineReducers} from redux; // 用于合并多个reducer文件,便于管理的

import banner from './bannerReducer.js';
import user from './userReducer.js';

// 经过实践,笔者发现在使用时如果调用的是state.js存储数据,会同时返回两次,
// 所以在reducers文件中各自创建了数据对象,便于分开管理。
const reducer = combineReducers({ 
    bannerState: bannerReducer,
    userState: userReducer
})


export default reducer;
// /store/reducers/userReducer.js
const defaultState = { // 这个常量名没什么特别含义, 大家自己开心就好
    loginStatus: false
}
// 喜欢用state.js可以这样引入,在下面会提到state.js的创建
import defaultState from '../state.js';

function loginOut(state = defaultState.loginStatus, action){
    // 最终返回给调用的数据, 两种写法取其一
    return Object.assign([], state, action.data,{
       userInfo: ''
    })
    return Object.assign([], state, action.data)
}

export default function userReducer(state = defaultState, action){
    // 根据传递的type调用对应的方法。
    switch(action.tyoe){
        case 'LOGIN_OUT':
            return loginOut(action.data);
        default:
            return state;
    }
}

三、创建action.js

如果只是少量的状态管理,是可以不要这个文件的,在下面会提到不通过action方法调用reducer

export function user(type, data){
  switch(type){
    case 'Login_out':
      return {
        type: 'LOGIN_OUT',
        data: data
      }
    case 'LOGIN_IN':
      return {
        type: 'LOGIN_IN',
        data: data
      }
  }
}

四、创建index.js

这个文件创建好了,就不用管了,轻松愉快

import {createStore} from 'redux';
import reducers from './reducers/mainReducer';

let store = createStore(reducers);

export default store;

五、创建state.js(可选)

如果创建state.js的话, 在reducer文件中引入并删除掉前面写的defaultState对象即可

但是前面也说了,类似我这种多个功能需要用到状态管理的, 在reducer中分别管理各自的state比较好处理点。

export default {
    loginStatue: false,
    showBanner: false
}

六、代码中调用redux

话不多说,开搞。

根据@一条鱼的心事大佬在评论区指出的关于订阅store的问题,这里我将两点都写出来,供大家参考,选择使用

如果不需要在当前界面针对store的修改做出变化是可以不用订阅store的state信息的。

import store from '../../store/index';
import {user} from '../../store/action';
constructor(props){
    super(props);
    // 订阅(监听)store值的变化,除非当前界面内会修改,否则是不需要写的
    store.subscribe(() => {
        this.setState({
            loginStatue: store.getState().userState['loginStatus']
        })
    })
}

componentDidMount(){
    // 调用action方法 -> 返回参数传给mainReducers -> 根据type找到对应的reducer方法
    store.dispatch(user('LOGIN_OUT', false}))
    // 直接调用mainReducers -> 根据type找到对应的reducer方法
    store.dispatch({type:'LOGIN_OUT', data: false})
},
// 使用订阅方法之后需要在组件卸载前前进行手动注销
componentWillUnmount(){
    store.unsubscribe();
}

来自一条鱼的心事大佬给出的最佳实践写法

// /src/Index.js;
// 在index.js文件处讲store方法挂载在root上,方便调用;
import store from './store/index';
window.$dispatch = store.dispatch;
window.$getState = store.getState;

// /src/pages/view.js;
import store from '../../store/index';
import {user} from '../../store/action';
import {connect, mapStateToProps} from 'react-redux';

class View extends Component{
    function mapStateToProps(state){
        return {
            loginStatus: $getState().user.loginStatus
        }
    }
    render(){
        return (
            <div></div>
        )
    }
}

export default connect(mapStateToProps)(View);

七、总结

这是我踩坑之后找到的比较简单灵活的redux调用方法, 如果还有更简单的希望能在评论区丢个链接。

最开始我看到一个使用成本很高的redux教程,差点弃坑滚回Vue了。

学习的路还长,一定要坚持下去。

希望觉得不错的看官给个赞支持下。谢谢