回顾 redux react-redux

最近在忙着写自己的react个人项目。现在用到redux这块,嗯,虽然之前写过,也回顾一下,但还是有点生疏,故在此写个简单的案例,回顾一下。

有兴趣的朋友可以 于此链接 redux初识。人毕竟有遗忘曲线

计数案例
create-react-app redux-test

cd redux-est

npm run start

运行成功,开始改造

新版本默认变成如下的了,不习惯可以改成class

import React from 'react';
import './App.css';

function App() {
  return (
    <div className="App">
      <div>ssss</div>
    </div>
  );
}

export default App;

函数定义组件 与 类组件的区别
  • 1.函数式组件不会被实例化,整体渲染性能得到提升

函数式组件被精简成一个 render 方法的函数,所以它没有组件实例化的过程,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升。同时的,函数式组件本身是没有 this 的,所以在使用 Ref 等模块时与类组件也会有所区别。

  • 2.函数式组件没有状态

函数式组件本身没有自己的内部状态 state,数据依赖于 props 的传入,所以它又称无状态组件。

  • 3.函数式组件无访问生命周期的方法

函数式组件是不需要组件生命周期管理,所以底层实现这种形式的组件时是不会实现组件的生命周期方法。

v1.0 不用redux
import React from 'react';
import './App.css';

export default class App extends React.Component {

    state = {
      count:0
    }
    constructor(props) {
      super(props)
      this.numberRef = React.createRef()
    }
    increment = ()=>{
        const number = this.numberRef.current.value*1
        this.setState(state => ({count:state.count + number}))
    }
    decrement = ()=>{
      const number = this.numberRef.current.value*1
      this.setState(state => ({count:state.count - number}))
    }
    incrementIfOdd = ()=>{
      const number = this.numberRef.current.value*1
      if(this.state.count % 2 === 1){
        this.setState(state => ({count:state.count + number}))
      }
    }
    incrementAsync = ()=>{
      const number = this.numberRef.current.value*1
      setTimeout(()=>{
        this.setState(state => ({count:state.count + number}))
      },1000)
    }
    render(){
      const count = this.state.count
      return(
        <div>
          <p>click {count} times</p>
          <div>
              <select ref={this.numberRef}>
                <option value = "1">1</option>
                <option value = "2">2</option>
                <option value = "3">3</option>
              </select>&nbsp;&nbsp;
              <button onClick={this.increment}>+</button>&nbsp;&nbsp;
              <button onClick={this.decrement}>-</button>&nbsp;&nbsp;
              <button onClick={this.incrementIfOdd}>incrementIfOdd</button>&nbsp;&nbsp;
              <button onClick={this.incrementAsync}>incrementAsync</button>
          </div>
        </div>
      )
    }
}


v2.0 利用redux
store.getState()
store.dispath(action)
store.subscribe(render)

store挂载在App父组件上,props传递store值,分了几个模块文件
在这里插入图片描述

npm install redux -S

redux/store.js

import {createStore } from "redux"

import reducer from "./reducer"

export default createStore(reducer)

redux/reducer.js

// 根据当前store和指定的action返回一个新的store

import { INCREMENT,DECREMENT} from "./action-type"

export default function count(state = 1,action) { // state的默认值可以先声明一个默认对象再赋值,这里就一个值就先这样简单处理
    console.log(state,action)
    switch (action.type) {
        case INCREMENT:
            return state + action.data
        case DECREMENT:
            return state - action.data
        default:
            return state;
    }
}

redux/action-type.js

/**
 * action type  统一定义,防止后续其他地方使用写错
 */

 export const INCREMENT = "increment"

 export const DECREMENT = "decrement"

redux/actions.js

/**
 * action creators   
 */

 import { INCREMENT,DECREMENT} from "./action-type"

 export const increment = (number) => ({type:INCREMENT,data:number})

 export const decrement = (number) => ({type:DECREMENT,data:number})

App.js

import React from 'react';
import PropTypes from 'prop-types'; 

import { increment,decrement } from "./redux/actions"
 
export default class App extends React.Component {
    static propTypes = {
      store:PropTypes.object.isRequired
    }

    state = {
      count:0
    }
    constructor(props) {
      super(props)
      this.numberRef = React.createRef()
    }
    increment = ()=>{
        const number = this.numberRef.current.value*1
       // this.props.store.dispatch({type:'INCREMENT',data:number}) // 不建议这样写,单独建一个actions文件
       this.props.store.dispatch(increment(number))
    }
    decrement = ()=>{
      const number = this.numberRef.current.value*1
      this.props.store.dispatch(decrement(number))
    }
    incrementIfOdd = ()=>{
      const number = this.numberRef.current.value*1
      if(this.props.store.getState() % 2 === 1){
        this.props.store.dispatch(increment(number))
      }
    }
    incrementAsync = ()=>{
      const number = this.numberRef.current.value*1
      setTimeout(()=>{
        this.props.store.dispatch(increment(number))
      },1000)
    }
    render(){
      const count = this.props.store.getState()
      return(
        <div>
          <p>click {count} times</p>
          <div>
              <select ref={this.numberRef}>
                <option value = "1">1</option>
                <option value = "2">2</option>
                <option value = "3">3</option>
              </select>&nbsp;&nbsp;
              <button onClick={this.increment}>+</button>&nbsp;&nbsp;
              <button onClick={this.decrement}>-</button>&nbsp;&nbsp;
              <button onClick={this.incrementIfOdd}>incrementIfOdd</button>&nbsp;&nbsp;
              <button onClick={this.incrementAsync}>incrementAsync</button>
          </div>
        </div>
      )
    }
}


index.js

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

import App from './App'

import store from './redux/store'

ReactDOM.render(<App store={ store } />, document.getElementById('root'));
// state更新监听
store.subscribe(()=>{ // state内部发生变化,回调 重新渲染
    ReactDOM.render(<App store={ store } />, document.getElementById('root'));
})

react-redux
  • Provider
  • connect()

展示组件

负责组件应用的UI层面,也就是如何渲染,具有很强的内聚性,不关心渲染的数据是如何取到的

容器组件

负责应用的逻辑处理,比如发送网络请求,处理返回数据,将处理好的数据传递给展示组件等

<Provider store = {store}> //自动subscribe

connect(
	state => ({})
	{action1,action2} // 返回的还是dispatch()
)(UI组件)
v3.1 react-redux

重新新建文件夹Counter,App,单独测试,redux文件不变
在这里插入图片描述
Counter.jsx

/**
 * ui组件
 */

import React from 'react';
import PropTypes from 'prop-types'; 

export default class Counter extends React.Component {
    static propTypes = {
      count:PropTypes.number.isRequired,
      increment: PropTypes.func.isRequired,
      decrement: PropTypes.func.isRequired,
    }

    state = {
      count:0
    }
    constructor(props) {
      super(props)
      this.numberRef = React.createRef()
    }
    increment = ()=>{
        const number = this.numberRef.current.value*1
        this.props.increment(number)
    }
    decrement = ()=>{
      const number = this.numberRef.current.value*1
      this.props.decrement(number)
    }
    incrementIfOdd = ()=>{
      const number = this.numberRef.current.value*1
      if(this.props.count % 2 === 1){
        this.props.increment(number)
      }
    }
    incrementAsync = ()=>{
      const number = this.numberRef.current.value*1
      setTimeout(()=>{
        this.props.increment(number)
      },1000)
    }
    render(){
      const count = this.props.count
      return(
        <div>
          <p>click {count} times</p>
          <div>
              <select ref={this.numberRef}>
                <option value = "1">1</option>
                <option value = "2">2</option>
                <option value = "3">3</option>
              </select>&nbsp;&nbsp;
              <button onClick={this.increment}>+</button>&nbsp;&nbsp;
              <button onClick={this.decrement}>-</button>&nbsp;&nbsp;
              <button onClick={this.incrementIfOdd}>incrementIfOdd</button>&nbsp;&nbsp;
              <button onClick={this.incrementAsync}>incrementAsync</button>
          </div>
        </div>
      )
    }
}

containers/App.js

import { connect } from "react-redux"

import Counter from "../components/Counter"

import { increment, decrement } from "../redux/actions"

/**
 * 容器组件 ,通过connect包装的UI组件(Counter)
 * 向UI组件传入特定的属性
 */

function mapStateToProps(state) {
    return {
        count: state
    }
}

function mapDispatchToProps(dispatch) {
    return {
        increment: (number) => dispatch(increment(number)),
        decrement: (number) => dispatch(decrement(number))
    }

}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Counter)

在起始位置的index.js改一下入口组件路径

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

import App from './containers/App' //修改

import store from './redux/store'

import { Provider } from 'react-redux'

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

v3.2 react-redux

containers/App.js 其他跟v3.1一样不变

import { connect } from "react-redux"

import Counter from "../components/Counter"

import { increment, decrement } from "../redux/actions"

export default connect(
    state => ({count:state}),
    {increment,decrement}
)(Counter)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值