react-redux 复习
redux
管理state
的容器, 用于状态管理
下载
yarn add react-redux redux
上一个小案例redux 小案例
<button onClick={()=>store.dispatch(addAction)}>++</button>
<button onClick={()=>store.dispatch(subAction)}>--</button>
新建文件
store/index.js
import {createStore} from "redux";
import reducer from "./reducer";
export default createStore(reducer);
store/action.js
export const addAction = { type: 'add' };
export const subAction = { type: 'sub' };
store/reducer.js
const defaultState = {
num: 0
}
const reducer = (state = defaultState, action) => {
return ({
add() {
return {...state,num: state.num + 1}
},
sub() {
return {...state,num: state.num - 1}
},
})[action.type]?.() || state;
}
export default reducer;
下面这种写法更清晰
const reducer = (state = initialState, action) => {
if (action.type === "INC") {
return { ...state, count: state.count + 1 };
}
return state;
};
createStore
创建store
对象store.dispatch
用来派发action
,action
会传递给store
store.getState
这个方法获取store
里的所有数据内容store.subscribe
让我们订阅store的改变
combineReducers
类型vuex 模块
const reducers = combineReducers({
userState: userReducer,
widgetState: widgetReducer
});
通过使用监听执行,拿到最新的值
store.subscribe(()=><App />)
react-redux
Provider
为后代组件提供storeconnent
为组件提供数据和数据变更的方法
import { useSelector } from 'react-redux'
export const CounterComponent = () => {
const counter = useSelector(state => state.counter)
const dispatch = useDispatch();
onClick={() => dispatch(incrementBird(bird.name))}>
return <div>{counter}</div>
}
redux
react-redux
redux-logger
redux-thunk
redux-toolkit
redux-saga
第二个版本
/redux/module/one_reducer.js
const defaultState = {
num: 100
}
const oneReducer = (state = defaultState, action) => {
if (action.type === 'addOne') {
//拿到函数传递的参数
console.log(action.data);
return {...state, num: state.num + 10}
}
if (action.type === 'subOne') {
return {...state, num: state.num - action.data}
}
return state
}
export default oneReducer;
/redux/module/reducer.js
const defaultState = {
num: 0
}
const reducer = (state = defaultState, action) => {
if (action.type === 'add') {
return {...state, num: state.num + 1}
}
if (action.type === 'sub') {
return {...state, num: state.num - 1}
}
return state
}
export default reducer;
/redux/action.js
// 加
export const addAction = {type: 'add'};
// 减
export const subAction = {type: 'sub'};
export const addOneAction = data => ({type: 'addOne', data});
export const subOneAction = data => ({type: 'subOne', data});
/redux/index.js
import {combineReducers, createStore} from "redux";
import reducer from "./module/reducer";
import oneReducer from "./module/one_reducer";
export default createStore(combineReducers({
a: reducer,
b: oneReducer
}));
修改入口文件
ReactDom.render(
<Provider store={store}>
<Square/>
</Provider>,
document.getElementById('root'))
使用
const Two = () => {
const counter=useSelector(state=>state.b.num)
const dispatch=useDispatch()
return (
<div>
Two
<h1>{counter}</h1>
<button onClick={()=>dispatch(subOneAction(20))}>--</button>
</div>
);
};
class One extends Component {
render() {
let {num1, num2, inc, add} = this.props;
return (
<div>
one
<h1>{num1}</h1>
{/*<button onClick={() => store.dispatch(addAction)}>++</button>*/}
<button onClick={() => inc()}>++</button>
<br/>
<button onClick={() => store.dispatch(subAction)}>--</button>
<br/>
<h1>{num2}</h1>
<button onClick={() => add({sex:10})}>++</button>
<Two />
</div>
);
}
}
// 读取数据, 通过props 接受
const mapState = state => {
return {
num1: state.a.num,
num2: state.b.num
}
}
// 自定义方法
const mapDispatch = dispatch => {
return {
inc: () => {
dispatch(addAction)
},
add: (num) => {
dispatch(addOneAction(num))
}
}
}
export default connect(mapState, mapDispatch)(One);
react-toolkit/ react-redux
store/module/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
export const slice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
increment: state => {
state.value += 1;
},
decrement: state => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
console.log(action);
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = slice.actions;
// 允许我们执行异步逻辑
export const incrementAsync = amount => dispatch => {
setTimeout(() => {
dispatch(incrementByAmount(amount));
}, 1000);
};
// `useSelector((state) => state.counter.value)`
export const selectCount = state => state.counter.value;
export default slice.reducer;
store/index.js
import {configureStore} from '@reduxjs/toolkit'
import counterReducer from "./module/counterSlice";
export default configureStore({
reducer: {
counter: counterReducer
},
})
入口文件
<Provider store={store}>
<Square/>
</Provider>,
使用
render() {
let {counter, dispatch} = this.props
return (
<div>
one
<h1>{counter.value}</h1>
<button onClick={() => dispatch(increment())}>click++</button>
<button onClick={()=>dispatch(incrementByAmount(10))}>传入值</button>
</div>
);
}
// 读取数据, 通过props 接受
const mapState = state => {
return {
counter: state.counter
}
}
// 自定义方法
const mapDispatch = dispatch => {
return {dispatch}
}
export default connect(mapState, mapDispatch)(One);
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬