实现一个简单的 Redux 功能库

首先简单说一下 Redux 在 React 项目中的用法。ReduxReact 之间并没有什么关系,脱离了 ReactRedux 也可以与其它的 js 库(甚至是原生 js)搭配使用,Redux 只是一个状态管理库,但它与 React 搭配使用时却很好用,使开发 React 应用更加简介。

这里实现一个简单的计数器功能,当鼠标点击按钮时数字就会加一。使用 React-Hooks 写一个 App 组件用来实现该功能:

import React,{
    useState } from "react";
function App(){
   
    let [count,setCount] = useState(0);
    function handleClick(){
   
        setCount(count + 1);
    }
    return (
        <div>
            <div>
                <h1>{
   count}</h1>
                <button onClick={
   handleClick}>Click</button>
            </div>
        </div>
    );
}
export default App;

然后渲染到页面的方法,写在 index.js 中:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
    <App />, 
    document.getElementById('root')
);

这样一个计数器组件就写好了。但是还没有使用 Redux。如果使用 Redux 就要把 React 中的状态(state)交给 Redux 管理。

创建 store

单纯的只使用 Redux 库时,需要先做“配置”,因为这些代码的书写是必不可少的。

这里直接说一下代码分离,代码分离后更好管理,有利于日后代码的改动。

下面是 Redux 的工作流:
redux工作流程图
首先,react 组件从 store 中获取原始的数据,然后渲染。当 react 中的数据发生改变时,react 就需要使用 action,让 action 携带新的数据值派发给 store,store 把数据发给 reducer 函数,reducer 函数处理新的数据然后返回给 store,最后 react 组件拿到更新后的数据渲染页面,达到页面更新的目的。

store 就是储存数据的地方。在 redux 中使用 createStore 存储数据。

这里新建一个 store 目录,里面是一个 index.js 文件,为了生成并导出一个 store:

import {
    createStore } from "redux";
import AppReducer from "../reducer/App.reducer.js";

// 该函数须传入一个 reducer 函数
// 要不然怎么与 reducer 进行通信
// 然后返回
const store = createStore(
    AppReducer
);

export default store;

在写组件时(当然,除了 UI 组件),我们都应该创建一个自己的 reducer 函数,这样方便管理。假如有两个组件:App 和 Home,那就最好创建两个 reducer 函数:appReducer 和 homeReducer。redux 中提供了一个 combineReducers 函数,这个函数可以将小的 reducer 合并成大的 reducer,并将合并后的 reducer 返回出去。于是可以进行改进上面的代码:

import {
    createStore, combineReducers, applyMiddleware } from "redux";
// App 组件的 reducer
import appReducer from "../reducer/app.reducer.js";
// Home 组件的 reducer
import homeReducer from "../reducer/home.reducer.js";

// 合并 reducer
const rootReducer = combineReducers({
   
    appReducer,
    homeReducer
});

// 给合并后的 reducer 创建 store
const store = createStore(
    rootReducer,
);
export default store;

reducer 函数

reducer 函数的默认格式是这样的:

// 首先定义一个默认的 state 对象,里面的属性和值是你这个页面的状态(props/state)默认现实的内容
// 在这个实例中,count 的默认值假如是 0

const DEFAULT_STATE = {
   
    count: 0
}
// 下面是 reducer 函数:
function reducer(state,action){
   
    switch(action.type){
   
        // 默认情况下,就返回原始的 state
        // 页面初始渲染的结果
        default: return state;
    }
}

一个 reducer 就编写好了,可以发现 reducer 函数中的第二个参数叫 action,通过上面的流程图应该就明白了,action 就是最左边的 action,它是组件与 store 通信的东西,action 通常是个对象,这个对象一般由两部分组成,一部分是数据,而另一部分就是 type 属性,这个属性用来标志 state 中更新哪些数据。type 的值其实就是唯一标识的字符串。比如下面的 对象就符合一个 action 的书写规范:

var action = {
   
    type: "SET_COUNT",
    count: 1
}

一般不把 action 直接写成一个对象,新建一个 action 目录,里面专门存放各个组件的 action,而且把 action 写成函数形式:

export function setCount(count){
   
    // 调用这个函数就会返回一个对象
    return {
   
        type: "SET_COUNT",
        count: count
    }
}

action 导出后,在组件中接收 action 函数,然后使用 action 函数。还有一点不足是,action.type 的书写不太好,这样写不好管理,因为 reducer 中也要用到 action.type,我们可以把字符串抽离出来专门由一个文件去维护。比如建立一个 types 目录,目录下存放每个组件会用到的 type 字符串。使用时引入即可。

export const SET_COUNT = "app/set_count";

那么 reducer 的函数就可以写成这样:

import {
    SET_COUNT } from "../types/appTypes";
const DEFAULT_STATE = {
   
    count: 0
}
// 下面是 reducer 函数:
function reducer(state,action){
   
    switch(action.type){
   
        // 如果 type 是 SET_COUNT 时,
        // count 值就变成 action 对象中的 count 值
        case SET_COUNT:
            return {
   
                count: action.count
            }
        // 默认情况下,就返回原始的 state
        // 页面初始渲染的结果
        default: return state;
    }
}

写到这里,就只剩下 react 与 action 的通信ÿ

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值