redux的基本使用
<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button>
<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>
<script>
// 1. 定义reducer函数
// 作用: 根据不同的action对象,返回不同的新的state
// state: 管理的数据初始状态
// action: 对象 type 标记当前想要做什么样的修改
function reducer (state = { count: 0 }, action) {
// 数据不可变:基于原始状态生成一个新的状态
if (action.type === 'INCREMENT') {
return { count: state.count + 1 }
}
if (action.type === 'DECREMENT') {
return { count: state.count - 1 }
}
return state
}
// 2. 使用reducer函数生成store实例
const store = Redux.createStore(reducer)
// 3. 通过store实例的subscribe订阅数据变化
// 回调函数可以在每次state发生变化的时候自动执行
store.subscribe(() => {
console.log('state变化了', store.getState())
document.getElementById('count').innerText = store.getState().count
})
// 4. 通过store实例的dispatch函数提交action更改状态
const inBtn = document.getElementById('increment')
inBtn.addEventListener('click', () => {
// 增
store.dispatch({
type: 'INCREMENT'
})
})
const dBtn = document.getElementById('decrement')
dBtn.addEventListener('click', () => {
// 减
store.dispatch({
type: 'DECREMENT'
})
})
// 5. 通过store实例的getState方法获取最新状态更新到视图中
</script>
redux和react
在React中使用redux,官方要求安装俩个其他插件 - Redux Toolkit 和 react-redux
1. Redux Toolkit(RTK)- 官方推荐编写Redux逻辑的方式,是一套工具的集合集,简化书写方式
2. react-redux - 用来 链接 Redux 和 React组件 的中间
3. 安装配套工具 npm i @reduxjs/toolkit react-redux
countStour(非异步)
import { createSlice } from '@reduxjs/toolkit'
const counterStore = createSlice({
name: 'count',
initialState: {
count: 0
},
// 方法
reducers: {
increment(state) {
state.count++
},
decrement(state) {
state.count--
},
addToNum(state, action) {
state.count += action.payload
}
}
})
// 结构出函数··
const { increment, decrement,addToNum } = counterStore.actions
// 获取reducer函数
const counterReducer = counterStore.reducer
export { increment, decrement,addToNum }
export default counterReducer
channelStore(异步)
import { createSlice } from '@reduxjs/toolkit'
const channelStore = createSlice({
name: 'channel',
initialState: {
list: []
},
// 方法
reducers: {
setChannels(state, action) {
state.list = action.payload
}
}
})
// 结构出函数··
const { setChannels } = channelStore.actions
// 异步操作
const URL = 'http://geek.itheima.net/v1_0/channels'
const fetchChannelList = () => {
return async (dispatch) => {
const res = await fetch(URL)
const data = await res.json()
dispatch(setChannels(data.data.channels))
}
}
// 获取reducer函数
const channelReducer = channelStore.reducer
export { fetchChannelList }
export default channelReducer
store.js整合counterStore 和channelStore
import {configureStore} from "@reduxjs/toolkit"
import counterReducer from "./modules/counterStore"
import channelStore from "./modules/channelStore"
const store = configureStore({
reducer :{
counter: counterReducer,
channel:channelStore
}
})
export default store
index.js入口文件中引入store
// react 核心包
import React from 'react';
import ReactDOM from 'react-dom/client';
// 根组件
import App from './App';
import store from './store'
import {Provider} from 'react-redux'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
在react组件中使用store
import { useDispatch, useSelector } from 'react-redux'
import { increment, decrement, addToNum } from '../store/modules/counterStore'
import { fetchChannelList } from '../store/modules/channelStore'
import { useEffect } from 'react';
function StoreRedux() {
const counter = useSelector(state => state.counter);
const channel = useSelector(state => state.channel);
const dispatch = useDispatch()
useEffect(() => {
dispatch(fetchChannelList())
}, [dispatch])
console.log(channel.list);
return (
<div>
<h1>redux</h1>
<button onClick={() => { dispatch(decrement()) }}>-</button>
<span>{counter.count}</span>
<button onClick={() => { dispatch(increment()) }}>+</button>
<button onClick={() => { dispatch(addToNum(10)) }}>+10</button>
<ul>
{channel.list.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
</div>
);
}
export default StoreRedux;