Redux+RTK@reduxjs/toolkit

Redux 是一种用于管理应用程序状态的 JavaScript 库。
它是一个可预测的状态容器,可以用于编写可维护和可扩展的应用程序。

@reduxjs/toolkit 是一个官方提供的 Redux 工具包,它可以帮助简化 Redux 应用程序的开发,并
提供常用的 Redux 原生方法,例如创建 Redux store、定义 reducer、处理异步操作等。

下面是一个使用 @reduxjs/toolkit 的示例:

安装

首先,我们需要安装 @reduxjs/toolkit 和 react-redux:


npm install @reduxjs/toolkit react-redux -S

作用于整个应用App,设置provieder组件

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <Provider store={store}>
   <App />
 </Provider>
);

创建 Redux Store

使用 @reduxjs/toolkit 创建 Redux store 非常简单,只需要调用 configureStore() 函数并传入
一个 reducer 即可:
在这里插入图片描述

import { configureStore } from '@reduxjs/toolkit';
import userReducer from './reducers/user';

const store = configureStore({
    reducer:{
        user:userReducer
    }
});
export default store;

上面的代码创建了一个 Redux store,并将应用程序的根 reducer 传递给 configureStore() 函
数。该函数返回的 store 对象是应用程序中唯一的数据源。

定义 Reducer

Reducer 是一个纯函数,它负责根据之前的状态和一个 action 返回一个新的状态。
使用@reduxjs/toolkit 创建 reducer 非常简单,只需要调用 createSlice() 函数即可:

简单例子:

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
	value: 0
	};

const counterSlice = createSlice({
		name: 'counter',
		initialState,
		
		reducers: {
			increment: (state) => {
				state.value += 1;
			},
			decrement: (state) => {
				state.value -= 1;
			},
			incrementByAmount: (state, action) => {
				state.value += action.payload;
			}
		}
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

上面的代码使用 createSlice() 函数创建了一个名为 counter 的 reducer,并定义了三个
action: increment 、 decrement 和 incrementByAmount 。每个 action 都是一个函数,它们负责根
据当前状态修改应用程序的数据。在这个例子中, incrementByAmount 还接受一个名为 payload 的
参数,该参数用于指定增量。

使用 useSelector

在使用 Redux 的过程中,我们经常需要访问 store 中的数据或者调用 action。
在 React 中,我们可以使用 useSelector() 和 useDispatch() 钩子来完成这些操作。

useSelector() 钩子允许我们从 store 中选择和提取数据。
例如,下面的代码演示了如何使用useSelector() 钩子获取 counter reducer 中的 value 值:

import { useSelector } from 'react-redux';

function Counter() {
const value = useSelector(state => state.counter.value);
return (
	<div>
	<span>{value}</span>
	</div>
);
}

使用 useDispatch

在 React 中使用 useDispatch 非常简单。首先需要导入 useDispatch :

import { useDispatch } from 'react-redux';
import { setLogin } from '../store/reducers/user' //取出行为

然后在组件中调用 useDispatch 函数,即可获取到 Redux 的 dispatch 函数:

const dispatch = useDispatch();

在组件中,我们可以使用 dispatch 函数来分发 Redux 的 Action。例如:

function ExampleComponent() {
	const dispatch = useDispatch();
	const handleClick = () => {
	dispatch(setLogin());
	};
	
	return (
		<button onClick={handleClick}>Click me!</button>
	);
}

上面的代码中,我们获取了 Redux 的 dispatch 函数,并在 handleClick 函数中分发了一个
INCREMENT 的 Action。

使用 createAsyncThunk

在 @reduxjs/toolkit 中使用 createAsyncThunk 可以更方便地编写异步操作的 Redux Action。
它可以自动创建三个 Action: pending 、 fulfilled 和 rejected ,用于处理异步操作的不同状态。

首先需要导入 createAsyncThunk :

import { createAsyncThunk } from '@reduxjs/toolkit';

然后,我们可以使用 createAsyncThunk 函数来创建异步操作的 Action。例如:

const fetchUser = createAsyncThunk('user/fetchUser', async (userId) => {
	const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
	const data = await response.json();
	return data;
});
// 在createSlice内添加
extraReducers: builder => {
// builder.addCase() 链式调用
// 成功状态
builder.addCase(fetchUser.fulfilled, (state, { payload }) => {
state.user = payload
})

完整例子

在这里插入图片描述

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import store from './store/index.js';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
   <App />
 </Provider>
);

reportWebVitals();

App.js

import './App.css';
import { addLoginCount, addLoginCountByNum, getTest } from './store/reducers/user'; // 取出行为
import { useDispatch, useSelector } from 'react-redux'
import { useEffect, useState } from 'react';
import { memo } from 'react';

// memo()可以实现缓存 props发生变化的时候,才更新
const Son = memo((props) => {
  console.log('子组件更新', props.num)
  const user = useSelector(state => state.user);
  return <h1>我是子组件{user.loginCount}</h1>
})

function App() {
  const user = useSelector(state => state.user);
  const dispath = useDispatch();
  const [num, setNum] = useState(1)
  console.log('user:', user);

  useEffect(() => {
    dispath(getTest());
  }, [])

  console.log(user.test, 'test');
  return (
    <div className="App">
      <div>
        {user.isLogin}
        {user.loginCount} ||
        {num} ||
        <pre>
          {user.test}
        </pre>
      </div>
      <button onClick={e => dispath(addLoginCount())}>更改loginCount+1</button>
      <button onClick={e => dispath(addLoginCountByNum(10))}>更改loginCount</button>
      <button onClick={e => setNum(num + 1)}>变更父组件</button>
      {/* 因为参数改变而更新 <Son num={num}/> */}

      {/* 不会更新 */}
      <Son />
    </div>
  );
}

export default App;

store/index.js

import { configureStore } from '@reduxjs/toolkit';
import userReducer from './reducers/user';
const store = configureStore({
    reducer:{
        user:userReducer
    }
});
export default store;

store/reducers/user.js

import { createSlice,createAsyncThunk } from '@reduxjs/toolkit'

// 异步
// Promise:padding, rejection ,fulfilled
export const getTest = createAsyncThunk('user/getTest',async ()=>{
   let res =  await fetch('http://localhost:3000/');
   let text = await res.text();
   console.log(text)
   return text; // fulfilled状态对应的值
});


let userSlice = createSlice({
    name:'user',
    initialState:{
        isLogin:false,
        loginCount:0,
        test:''
    },
    reducers:{
        addLoginCount(state){
            state.loginCount++;
        },
        addLoginCountByNum(state,action) {
            console.log(action);
            state.loginCount += action.payload;
        }
    },
    extraReducers(builder){
        // 当getTest fulfilled状态时,处理          // meta+type+payload
        builder.addCase(getTest.fulfilled,(state,{payload})=>{
            // 上述方法返回的结果payload
            state.test = payload;
        })
    }
})

// 外部组件来使用的action
export const {addLoginCount,addLoginCountByNum} = userSlice.actions;

// 默认导出是所有的reducer 供store注册这些方法
export default userSlice.reducer;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值