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

  1. Provider 为后代组件提供store
  2. connent 为组件提供数据和数据变更的方法
 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);
posted @ 2021-05-06 00:20  猫神甜辣酱  阅读(105)  评论(0编辑  收藏  举报