Login
芋圆社区 > 编程 > React > 状态管理工具Redux和hook

状态管理工具Redux和hook

903
0
2022-06-23
2022-10-13
Hey、小怪兽


React Redux


  • • Redux 是 JavaScript 应用的状态容器,提供可预测的状态管理,安装
  • npm i redux react-redux --save
  • • 下面来介绍普通的用法(不直接用hook用法是因为hook是React16.8的新增特性,有些项目React版本低的,比如我公司的老项目)
  • • 首先先创建一个React的项目,删除src里的所有内容,然后在src建一个store文件夹(里面建index.js和reducer.js),src目录下再建App1.jsx,index.js,不需要App.jsx
  • • 在store/reducer.js写:
  • // 定义状态
    const defaultState = {
        msg: "hello world!",
    };
    
    // 导出函数
    export default (state = defaultState) => {
        return state;
    };
  • • 这里会看到一个警告,提示不允许导出一个箭头函数
  • • 加上这一行代码就可以了,意思是让eslint忽略下一行
  • // eslint-disable-next-line
    export default (state = defaultState) => {
        return state;
    };
  • • 在store/index.js写:
  • import reducer from "./reducer";
    import { createStore } from "redux";
    
    const store = createStore(reducer);
    export default store;
  • • 接着回到src/index.js:
  • import React from "react";
    import ReactDOM from "react-dom/client";
    import App from "./App1";
    import { Provider } from "react-redux";
    import store from "./store";
    
    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(
        <React.StrictMode>
            // 在这下面的都可以用store
            <Provider store={store}>
                <App />
            </Provider>
        </React.StrictMode>
    );
  • • 最后在src/App1.jsx里加上:
  • import React, { Fragment } from "react";
    import { connect } from "react-redux";
    
    function App1(props) {
        return (
            <Fragment>
                <div>{props.msg}</div>
            </Fragment>
        );
    }
    
    // state映射
    const mapStateToProps = (state) => {
        return {
            msg: state.msg,
        };
    };
    
    // connect(state映射, dispatch映射)(当前组件类)
    export default connect(mapStateToProps)(App1);
  • • 这样页面会显示store里面的msg了,但如果需要增加一个按钮修改这个msg的话,要用到别的:
  • const mapDispatchToProps = (dispatch) => {
        return {
            // 这里和上面一样的key-value写法
            // changeMsg() {}就是changeMsg: function() {}的简写
            changeMsg(arg) {
                const action = { type: "changeMsgFn", value: arg };
                dispatch(action);
            },
        };
    };
    
    export default connect(mapStateToProps, mapDispatchToProps)(App1);
  • • 上面的也要修改:
  • function App1(props) {
        return (
            <Fragment>
                <div>{props.msg}</div>
                <button onClick={() => props.changeMsg("你好世界!")}>修改msg</button>
            </Fragment>
        );
    }
  • • 为啥要这样写onClick={() => props.changeMsg("你好世界!")},其实也相当于这样
  • function App1(props) {
        // 相当于在外面写
        const fn = () => props.changeMsg("你好世界!");
    
        return (
            <Fragment>
                <div>{props.msg}</div>
                <button onClick={fn}>修改msg</button>
            </Fragment>
        );
    }
  • • 去掉()=>会立刻执行changeMsg函数
  • function App1(props) {
        return (
            <Fragment>
                <div>{props.msg}</div>
                // 会立刻执行changeMsg函数,没有点击按钮,msg会立刻被你好世界替换
                <button onClick={props.changeMsg("你好世界!")}>修改msg</button>
            </Fragment>
        );
    }
  • • 不传参可以这样写,去掉()
  • <button onClick={props.changeMsg}>修改msg</button>
    
    // 但是下面的方法也要修改成
    changeMsg() {
        const action = { type: "changeMsgFn", value: "不传参" };
        dispatch(action);
    },
  • • 完整的src/App1.jsx代码
  • import React, { Fragment } from "react";
    import { connect } from "react-redux";
    
    function App1(props) {
        return (
            <Fragment>
                <div>{props.msg}</div>
                <button onClick={() => props.changeMsg("你好世界!")}>修改msg</button>
            </Fragment>
        );
    }
    
    const mapStateToProps = (state) => {
        return {
            msg: state.msg,
        };
    };
    
    const mapDispatchToProps = (dispatch) => {
        return {
            changeMsg(arg) {
                const action = { type: "changeMsgFn", value: arg };
                dispatch(action);
            },
        };
    };
    
    export default connect(mapStateToProps, mapDispatchToProps)(App1)
  • • 因为我们加了方法,还要修改store/reducer.js
  • const defaultState = {
        msg: "hello world!",
    };
    
    // 这里接收了action,通过action.type判断方法,然后赋值将传的value赋值给msg
    // eslint-disable-next-line
    export default (state = defaultState, action) => {
        // 这里深拷贝了一份state是因为不能直接修改state
        let newState = JSON.parse(JSON.stringify(state));
    
        switch (action.type) {
            case "changeMsgFn":
                newState.msg = action.value;
                break;
            default:
                break;
        }
        return newState;
    };
  • • 点击按钮后就会将msg的初始值"hello world!"替换成"你好世界!"

hook写法


  • • useSelector:读取redux的state的数据,要注意的是必须在函数组件中使用,因为底层是hooks实现的
  • import React, { Fragment } from "react";
    import { useSelector } from "react-redux";
    
    function App1() {
        const msg = useSelector((state) => state.msg);
        // 假如多个变量的话可以解构赋值
        // const { msg, msg2 } = useSelector((state) => state);
    
        return (
            <Fragment>
                <div>{msg}</div>
            </Fragment>
        );
    }
    
    export default App1;
  • • useDispatch : 修改redux的state的数据,它会返回dispatch方法,发送对应的action就可以了
  • import React, { Fragment } from "react";
    import { useSelector, useDispatch } from "react-redux";
    
    function App1() {
        const dispatch = useDispatch();
        const msg = useSelector((state) => state.msg);
    
        const changeMsg = () => {
            dispatch({ type: "changeMsgFn", value: "你好世界!" });
        };
    
        return (
            <Fragment>
                <div>{msg}</div>
                <button onClick={changeMsg}>修改msg</button>
            </Fragment>
        );
    }
    
    export default App1;
  • • 如果要传参数可以写成
  • import React, { Fragment } from "react";
    import { useSelector, useDispatch } from "react-redux";
    
    function App1() {
        const dispatch = useDispatch();
        const { msg } = useSelector((state) => state);
    
        const changeMsgFn = (arg) => {
            dispatch({
                type: "changeMsgFn",
                value: arg,
            });
        };
    
        return (
            <Fragment>
                <div>{msg}</div>
                <button onClick={() => changeMsgFn("你好")}>修改msg</button>
                <button onClick={() => changeMsgFn("再见")}>修改msg</button>
            </Fragment>
        );
    }
    
    export default App1;
  • • 其他的store/index.js和store/reducer.js的代码不变

上一篇:获取用户操作系统和浏览器信息

Message Board
回复
回复内容不允许为空
留言字数要大于2,小于200!
提交成功,5s后刷新页面!
编程导航

react-device-detect

react-html-parser

获取用户操作系统和浏览器信息

状态管理工具Redux和hook

Copyright © 2020 芋圆社区

Powered by 浙ICP备2020039309号-1

此页面不支持夜间模式!

已进入夜间模式!

已进入普通模式!

搜索框不允许为空

签到成功!经验+5!芋圆币+2!

签到失败!今日已签到!

需要登录社区账号才可以进入!

复制成功
寄,页面未加载完成或页面无锚点