React-Redux结合@Reduxjs/Toolkit实现函数组件化(数据持久化,刷新页面数据不丢)

函数式组件和类式组件的优缺点儿

函数组件(Function Component)和类组件(Class Component)是React中的两种定义组件的方式。函数组件是以一个函数的方式定义组件,而类组件则是以ES6的类继承React.Component来定义组件。

函数组件的优点:

1.更简单的代码,无需使用this关键字。
2.更容易理解和调试,因为它们是纯函数。
3.更好的性能,因为它们不支持shouldComponentUpdate生命周期钩子。
默认的性能优化,如React Fiber的diff算法会更好地处理函数组件。

函数组件的缺点:

1.缺乏状态(state),需要使用hooks API(如useState)。
2.缺乏生命周期方法,需要使用hooks API(如useEffect)或者将函数组件转换为类组件。
3.不支持refs。

类组件的优点:

1.支持更多的React特性,如状态(state),生命周期方法,refs等。
2.可以在任何生命周期中使用this.setState来更新状态,而不需要考虑是否在合成事件中。
3.类组件可以复用状态逻辑和生命周期逻辑,通过高阶组件等方式。

类组件的缺点:

1.需要使用this关键字,可能会导致this指向问题。

2.类组件在每次渲染时都会创建一个新的实例,可能会影响性能。
3.代码可能会更复杂,因为需要处理this和生命周期方法。
在新的React项目中,推荐使用函数组件,特别是对于简单的组件,因为它们更易于理解和维护。但是,当需要使用state、refs或生命周期方法时,就应该使用类组件或hooks

代码示例

主入口文件index.js 代码配置项如下:
import ReactDOM from "react-dom/client";
import React from "react";
import App from "./App";
import { Provider } from "react-redux";
//数据持久化,刷新页面数据不丢
import { PersistGate } from "redux-persist/integration/react";
//store 存储及数据持久化
import { store, persistor } from "./store/index";
const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(
  <React.StrictMode>
    {/* 全局提供核心 store */}
    <Provider store={store}>
      {/* 提供持久化入口 */}
      <PersistGate loading={null} persistor={persistor}>
        <App></App>
      </PersistGate>
    </Provider>
  </React.StrictMode>
);
Store 核心文件代码配置如下:
import { configureStore, combineReducers } from "@reduxjs/toolkit";
import personReducer from "./reducers/personReducer";
import { persistStore, persistReducer } from "redux-persist";
// import storage from 'redux-persist/lib/storage'; // 使用local storage来持久化存储
import storageSession from "redux-persist/lib/storage/session"; // 使用session  storage 临时会话模式

// 定义root reducer
const rootReducer = {
  person: personReducer,
};

// 配置持久化选项,localStorage模式
const persistConfig = {
  key: "root",
  // storage:storage,//local storage 存储模式
  storage: storageSession, //session storage 会话模式存储模式存储
};
//让所有的reducer,持久化
const persistedReducer = persistReducer(
  persistConfig,
  combineReducers({ person: personReducer })
);
export const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false,
    }),
});
//导出持久化配置
export const persistor = persistStore(store);

store 目录下 reducer 目录下personReducer.js配置如下:
import { createSlice } from "@reduxjs/toolkit";

const personSlice = createSlice({
  name: "person",
  initialState: {
    personList: [],
  },
  reducers: {
    addPerson: (state, action) => {
      state.personList = [action.payload, ...state.personList];
    },
  },
});

//分别导出所有的工作
export const { addPerson } = personSlice.actions;
//默认导出reducer动作
export default personSlice.reducer;

####### Person.js 页面组件代码如下:

import { useRef, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { nanoid } from "nanoid";
import { addPerson } from "../../store/reducers/personReducer";
export default function Person() {
  //通过ref 方式获取用户名称
  const userNameRef = useRef();
  //通过受控组件模式获取年龄
  const [age, setAge] = useState(0);
  //通过useSelect获取state
  const personList = useSelector((state) => state.person.personList);
  //通过调用useDispatch 分发action
  const dispatch = useDispatch();

  //添加用户
  function addUser() {
    const obj = { userName: userNameRef.current.value, age: age, id: nanoid() };
    //分派,分发
    dispatch(addPerson(obj));
  }
  //通过受控组件的模式获取年龄的值
  function getAgeValue(e) {
    setAge(e.target.value);
  }
  return (
    <div>
      <div>
        <label htmlFor="userName">用户名:</label>
        <input type="text" id="userName" name="userName" ref={userNameRef} />
      </div>
      <div>
        <label htmlFor="age">年龄:</label>
        <input type="text" id="age" name="age" onChange={getAgeValue} />
      </div>
      <div>
        <button onClick={addUser}>添加用户</button>
        <button>异步获取用户信息</button>
      </div>
      <hr />
      <div>用户信息显示:</div>
      <ul>
        {personList.map((item) => {
          return (
            <li key={item.id}>
              {item.userName}-{item.age}-{item.id}
            </li>
          );
        })}
      </ul>
    </div>
  );
}

页面效果如下:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值