react-redux的使用

认识 react-redux

react-redux 是一个 react 的插件库,它是专门用来简化 react 应用中使用 redux的

传送门

react-redux 的使用

react-redux 相关 API

Provider

让所有组件都可以得到 state 数据

<Provider store={store}>
   <App />
</Provider>
connect()

用于包装 UI 组件生成容器组件

export default connect(mapStateToProps, mapDispatchToProps)(Counter);
mapStateToprops()

将外部的数据(即state对象)转换为UI组件的标签属性

const mapStateToProps = (state) => {
  return {
    counter: state.counter
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    increment: (value) => {
      dispatch(createIncrementAction(value));
    },
    decrement: (value) => {
      dispatch(createDecrementActio(value));
    }
  }
}
mapDispatchToProps()

将分发action的函数转换为UI组件的标签属性

const mapDispatchToProps = (dispatch) => {
  return {
    increment: (value) => {
      dispatch(createIncrementAction(value));
    },
    decrement: (value) => {
      dispatch(createDecrementActio(value));
    }
  }
}

传送门

redux-thunk的使用

处理异步编程的问题

store.js

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducer';

let store = createStore(reducer, composeWithDevTools(applyMiddleware(thunk)));

export default store;
export const createIncrementAsyncAction = () => {
  return (dispatch) => {
    axios.get("http://localhost:3000/banner").then(res => {
      const data = res.data.data
      dispatch(createChangeBannersAction(data.banners));
    })
  }
}

reducer 的合并

import {combineReducers} from 'redux';
const reducer = composeEnhancers({
  counterInfo: counterReducer,
  bannersInfo: bannersReducer
});

redux 调试工具的使用

默认是不那个用的需要进行简答的处理,两种方法:

1、安装依赖包redux-devtools-extension,修改 store.js 文件

import { composeWithDevTools } from 'redux-devtools-extension'

const store = createStore(
  reducer,
  composeWithDevTools(applyMiddleware(thunk)) 
)

2、引入 composeEnhancers

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducer';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
let store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)));

export default store;

传送门

举例

实现一个简答的计数器,功能大致如下

在这里插入图片描述

不使用 redux
import React, { Component } from 'react';

class App extends Component {
  constructor() {
    super();
    this.state = {
      counter: 0
    }
  }

  render() {
    return (
      <div>
        <h2>当前计数:{this.state.counter}</h2>
        <select ref="selectRef">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
        <button onClick={() => {this.increment()}}>+</button>
        <button onClick={() => {this.decrement()}}>-</button>
        <button onClick={() => {this.incrementAsync()}}>一秒后再加</button>
      </div>
    );
  }

  increment() {
    const { value } = this.refs.selectRef;
    let { counter } = this.state;
    counter += Number(value);
    this.setState({
      counter
    });
  }

  incrementAsync() {
    setTimeout(() => {
      this.increment();
    }, 1000);
  }

  decrement() {
    const { value } = this.refs.selectRef;
    let { counter } = this.state;
    counter -= Number(value);
    this.setState({
      counter
    });
  }
}

export default App;

使用 redux

index.js

import React from "react";
import ReactDOM from "react-dom";

import App from "./App";
import store from "./store/store";

ReactDOM.render(<App store={store}/>, document.getElementById("root"));

// 监听 state 的变化
store.subscribe(() => {
  ReactDOM.render(<App store={store}/>, document.getElementById("root"));
})

App.js

import React, { Component } from 'react';
import { createDecrementActio, createIncrementAction } from './redux/createActions'

class App extends Component {
  
  componentDidMount() {
    console.log(this.props.store);
  }

  render() {
    const { counter } = this.props.store.getState();
    return (
      <div>
        <h2>当前计数:{counter}</h2>
        <select ref="selectNumberRef">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
        <button onClick={() => {this.increment()}}>+</button>
        <button onClick={() => {this.decrement()}}>-</button>
        <button onClick={() => {this.incrementAsync()}}>async</button>
      </div>
    );
  }

  increment() {
    const store = this.props.store;
    let { value } = this.refs.selectNumberRef;
   
    store.dispatch(createIncrementAction(Number(value)));
  }

  incrementAsync() {
    const store = this.props.store;
    let { value } = this.refs.selectNumberRef;

    setTimeout(() => {
      store.dispatch({
        type: 'incrementAsync',
        data: Number(value)
      })
    }, 1000);
  }

  decrement() {
    const store = this.props.store;
    let { value } = this.refs.selectNumberRef;
    
    store.dispatch({
      type: 'decrement',
      data: Number(value)
    })
  }
}

export default App;

index.js

import React from "react";
import ReactDOM from "react-dom";

import App from "./App";
import store from "./redux/store";

ReactDOM.render(<Redux store={store}/>, document.getElementById("root"));

// 监听 state 的变化
store.subscribe(() => {
  ReactDOM.render(<Redux store={store}/>, document.getElementById("root"));
})

store 文件夹

store.js

import { createStore } from 'redux';
import reducer from './reducer';
// 创建 store
const store = createStore(reducer);

export default store;

reducer.js

import { INCREMENT, DECREMENT } from './actionTypes';

const defaultState = {
  counter: 1
}

function handleCounter(preState = defaultState, action) {
  console.log(action);
  let newState;
  switch (action.type) {
    case INCREMENT:
      newState = {
        counter: preState.counter + action.data
      };
      return newState;

    case 'incrementIfOdd':
      newState = {
        counter: preState.counter + action.data
      };
      return newState;

    case 'incrementAsync':
      newState = {
        counter: preState.counter + action.data
      };
      return newState;
    case DECREMENT:
      newState = {
        counter: preState.counter - action.data
      };
      return newState;
    default:
      return preState;
  }
}

export default handleCounter;

createActions.js

import { INCREMENT, DECREMENT, INCREMENTASYNC } from './actionTypes';
export const createIncrementAction = value => ({
  type: INCREMENT,
  data: value
})

export const createDecrementActio = value => ({
  type: DECREMENT,
  data: value
})


export const createIncrementAsyncAction = (value, delay) => {
  return (dispatch) => {
    setTimeout(() => {
      dispatch(createIncrementAction(value, delay));
    }, delay);
  }
}

actionTypes.js

export const INCREMENT = 'increment';
export const DECREMENT = 'decrement';
export const INCREMENTASYNC = 'incrementAsync';
使用 react-redux

index.js

import React from "react";
import ReactDOM from "react-dom";

import App from "./App";
import store from "./store/store";


import { Provider } from "react-redux";

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

将 App.js 进行拆分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pA5syu64-1597136908932)(C:\Users\27857\Desktop\QQ截图20200811153735.png)]

counter.jsx

import React, { Component } from 'react';

class Counter extends Component {
  
  componentDidMount() {
    console.log(this.props)
  }

  render() {
    return (
      <div>
        <h2>当前计数:{this.props.counter}</h2>
        <select ref="selectNumberRef">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
        <button onClick={() => {this.increment()}}>+</button>
        <button onClick={() => {this.decrement()}}>-</button>
        <button onClick={() => {this.incrementIfOdd()}}>odd</button>
        <button onClick={() => {this.incrementAsync()}}>async</button>
      </div>
    );
  }

  increment() {
    let { value } = this.refs.selectNumberRef;
    this.props.increment(Number(value));
  }

 
  incrementAsync() {
    let { value } = this.refs.selectNumberRef;
    this.props.incremenAsync(Number(value), 1000);
    
  }

  decrement() {
    let { value } = this.refs.selectNumberRef;
    this.props.decrement(Number(value));
  }
}

export default Counter;

counter_container.js

import { connect } from 'react-redux';
import Counter from '../components/counter';
import { createDecrementActio, createIncrementAction, createIncrementAsyncAction } from '../redux/createActions';

const mapStateToProps = (state) => {
  return {
    counter: state.counter
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    increment: (value) => {
      dispatch(createIncrementAction(value));
    },
    decrement: (value) => {
      dispatch(createDecrementActio(value));
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

可以对上面进行简单优化

export default connect(
  state =>({
    counter: state.counter
  }),
  {
    increment: createIncrementAction,
    decrement: createDecrementActio,
    incremenAsync: createIncrementAsyncAction
  }
)(Counter)

connect 函数的作用

function connect(fn) {
  return (value) => {dispatch(fn(value))}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值