阅读 512

React:Redux/Redux-thunk/react-redux使用

redux

redux的是一个集中式的数仓,适用于多个组件数据源的情况,维护同一个数据样本,保持各个组件的一致性。

使用

  1. 创建一个store,接收reducer参数
// store/index.js
import { createStore, applyMiddleware, compose } from 'redux';
import reducer from './reducer';
import thunk from 'redux-thunk';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENTION_COMPOSE__ ?
  window.__REDUX_DEVTOOLS_EXTENTION_COMPOSE__() :
  compose;
const enhancer = composeEnhancers(applyMiddleware(thunk));

const store = createStore(reducer, enhancer);
export default store;
复制代码

reducer是处理action的派发,正确返回state的管理者

import { CHANGE_INPUT, ADD_ITEM, DELETE_ITEM, GET_LIST } from './actionTypes';
const defaultState = {
  inputValue: 'write Something',
  list: ['测试1', '测试2'],
};
export default (state = defaultState, action) => {
  let newState = JSON.parse(JSON.stringify(state));
  console.log(action);
  if (action.type === CHANGE_INPUT) {
    newState.inputValue = action.value;
  } else if (action.type === ADD_ITEM) {
    console.log('456');
    newState.list.push(newState.inputValue);
  } else if (action.type === DELETE_ITEM) {
    newState.list.splice(action.index, 1);
  } else if (action.type === GET_LIST) {
    newState.list = action.data.data;
  }
  return newState;
};
复制代码

将actionType和actionCreators抽离

// store/actionTypes.js
export const CHANGE_INPUT = 'changeInput';
export const ADD_ITEM = 'addItem';
export const DELETE_ITEM = 'deleteItem';
export const GET_LIST = 'getList';
复制代码
// store/actionCreators.js
import { CHANGE_INPUT, ADD_ITEM, DELETE_ITEM, GET_LIST } from './actionTypes';
import axios from 'axios';
const changeInputAction = value => ({
  type: CHANGE_INPUT,
  value,
});
const AddItemAction = () => ({
  type: ADD_ITEM,
});
const DeleteItemAction = index => ({
  type: DELETE_ITEM,
  index,
});
const getList = data => ({
  type: GET_LIST,
  data,
});
const getListThunk = () => dispatch => {
axios.get('https://www.fastmock.site/mock/dc49e8a7c9c73a80db073480577b1fc4/list/data').then(res => {
    console.log(res.data);
    const { data } = res;
    const action = getList(data);
    dispatch(action);
  });
};
export { changeInputAction, AddItemAction, DeleteItemAction, getList, getListThunk };
复制代码

react-redux使用

将组件的视图和数据剥离,使用到store的纯UI组件无状态,所有数据和方法都是从props而来

import React, { useEffect } from 'react';
import 'antd/dist/antd.css';
import { Input, Button, List } from 'antd';
import { connect } from 'react-redux';
import { changeInputAction, AddItemAction, DeleteItemAction, getListThunk } from './store/actionCreators';
const TodoList = props => {
  useEffect(() => {
    props.getList();
  }, []);
  return (
    <>
      <div>
        <Input value={props.inputValue} onChange={props.inputChange} style={{ width: '250px', marginRight: '10px' }} />
        <Button onClick={props.addItem}>增加</Button>
      </div>
      <div style={{ width: '300px', margin: '10px' }}>
        <List
          bordered
          dataSource={props.list}
          renderItem={(item, index) => <List.Item onClick={() => props.deleteItem(index)}>{item}</List.Item>}
        />
      </div>
      <div />
    </>
  );
};
const mapStateToProps = state => ({
  inputValue: state.inputValue,
  list: state.list,
});
const mapDispatchToProps = dispatch => ({
  inputChange(e) {
    let action = changeInputAction(e.target.value);
    dispatch(action);
  },
  addItem() {
    let action = AddItemAction();
    dispatch(action);
  },
  deleteItem(index) {
    let action = DeleteItemAction(index);
    dispatch(action);
  },
  getList() {
    let action = getListThunk();
    dispatch(action);
  },
});
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);
复制代码

使用到这个UI组件时外层会有一个provider提供store,connect的作用就是将store的state和dispath与UI组件的属性做一个一一映射。

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList';
import { Provider } from 'react-redux';
import store from './store';
const app = (
  <Provider store={store}>
    <TodoList />
  </Provider>
);
ReactDOM.render(app, document.getElementById('root'));
复制代码

redux-thunk的使用

const getList = data => ({
  type: GET_LIST,
  data,
});
const getListThunk = () => dispatch => {
  axios.get('https://www.fastmock.site/mock/dc49e8a7c9c73a80db073480577b1fc4/list/data').then(res => {
    console.log(res.data);
    const { data } = res;
    const action = getList(data);
    dispatch(action);
  });
};
复制代码

之前redux只能派发的action只能是一个对象,有了thunk中间件,可以是一个函数

文章分类
前端
文章标签