react基础<Ⅳ>

Day4使用react+redux来重构代码

三种:

  1. 原生js+redux
  2. js变成了react(ReactDOM.render那部分)
  3. react-redux

其中1、2的区别是:1是整个div刷新,2是只刷新{this.props.value}(利用dom diff)
那么
为什么要使用react-redux ,一起来看看三个版本的比较与差异
!版本1----App.js无法直接用store,而是要用this.props一层一层的往上调用store
!版本2----可以直接使用store,但是要获取store要一层一层的往下传,每个组件都要传store={this.props.store}
!版本3----react-redux重构

代码如下:

版本1----App.js无法直接用store,而是要用this.props一层一层的往上调用store

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {createStore} from 'redux'
import { stringLiteral } from '@babel/types';

const stateChanger = (state, action)=>{
    if(state === undefined){
        return 0
    }else{
        if(action.type === 'add'){
            var newState = state + action.payload
            return newState
        }else{
            return state
        }
    }
    
    return newState
}
const store = createStore(stateChanger)
render()
store.subscribe(()=>{
    render()
})//等价于store.subscribe(render)

function addIf(){
    if(store.getState() % 2 === 1){
        store.dispatch({type:'add', payload:1})
    }
}
function add1After(){
    setTimeout(()=>{
        store.dispatch({type:'add', payload:1})
    },2000)
}
function render(){
    ReactDOM.render(<App value={store.getState()}
    onAdd1={()=>{store.dispatch({type:'add', payload:1})}}
    onAdd2={()=>{store.dispatch({type:'add', payload:2})}}
    onAddIf={addIf}
    onAdd1After={add1After}
    />, document.getElementById('root'));
}
//App.js
import logo from './logo.svg';
import './App.css';
import React, { Component } from 'react'; 

class App extends Component {
  add1(){
    this.props.onAdd1()
  }
  add2(){
    this.props.onAdd2()
  }
  addIf(){
    this.props.onAddIf()
  }
  add1After(){
    this.props.onAdd1After()
  }
  render(){
    return (
    <div>
      你点击了<span id="value">{this.props.value}</span>次
      <div>
        <button id="add1" onClick={()=> this.add1()}>+1</button>
        <button id="add2" onClick={()=> this.add2()}>+2</button>
        <button id="addIfOdd" onClick={()=>this.addIf()}>如果是单数就+1</button>
        <button id="add1After2Sec" onClick={()=>this.add1After()}>两秒后+1</button>
      </div>
    </div>
  );
  }
}

export default App;

关于箭头函数:
1.函数不需要传参

store.subscribe(()=>{
    render()
})//等价于store.subscribe(render)

注意:我们是将函数作为参数传给subscribe,而不是将函数值传给subscribe
如果改变一下写法:

store.subscribe(render())//这种就是将render函数的函数值传给了subscribe,就会报错

2.函数需要传参

A.b(()=>{
    c(d)
})

注意:如果我要传的函数有参数,就一定要使用箭头函数

react比原生js好的地方就是:不需要整体更新div,而是可以根据dom diff来寻找需要更新的地方

版本2----可以直接使用store,但是要获取store要一层一层的往下传,每个组件都要传store={this.props.store}

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {createStore} from 'redux'
import { stringLiteral } from '@babel/types';

const stateChanger = (state, action)=>{
    if(state === undefined){
        return 0
    }else{
        if(action.type === 'add'){
            var newState = state + action.payload
            return newState
        }else{
            return state
        }
    }
    
    return newState
}
const store = createStore(stateChanger)
render()
store.subscribe(()=>{
    render()
})//等价于store.subscribe(render)

function addIf(){
    if(store.getState() % 2 === 1){
        store.dispatch({type:'add', payload:1})
    }
}
function add1After(){
    setTimeout(()=>{
        store.dispatch({type:'add', payload:1})
    },2000)
}
function render(){
    ReactDOM.render(<App value={store.getState()} store={store}/>, document.getElementById('root'));
}

   
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

//App.js
import logo from './logo.svg';
import './App.css';
import React, { Component } from 'react'; 

class App extends Component {
  add1(){
    this.props.store.dispatch({type:'add', payload:1})
  }
  add2(){
    this.props.store.dispatch({type:'add', payload:2})
  }
  addIf(){
    if(this.props.value % 2 === 1){
       this.props.store.dispatch({type:'add', payload:1})
    }
  }
  add1After(){
    setTimeout(()=>{
      this.props.store.dispatch({type:'add',payload:1})
    },2000)
  }
  render(){
    return (
    <div>
      你点击了<span id="value">{this.props.value}</span>次
      <div>
        <button id="add1" onClick={()=> this.add1()}>+1</button>
        <button id="add2" onClick={()=> this.add2()}>+2</button>
        <button id="addIfOdd" onClick={()=>this.addIf()}>如果是单数就+1</button>
        <button id="add1After2Sec" onClick={()=>this.add1After()}>两秒后+1</button>
      </div>
    </div>
  );
  }
}

export default App;

两个版本不相上下,一样麻烦,所以引入react-redux

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { createStore } from 'redux'
import { stringLiteral } from '@babel/types';
import { Provider } from 'react-redux'

const reducer = (state, action) => {
//也就是stateChanger
//根据旧的state产生新的state,前面的所有都可以改
    if (state === undefined) {
        return {n: 0}
    } else {
        if (action.type === 'add') {
            var newState = {n: state.n + action.payload}
            return newState
        } else {
            return state
        }
    }
}
const store = createStore(reducer)

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


// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

//App.js
import logo from './logo.svg';
import './App.css';
import React, { Component } from 'react';
import { connect } from "react-redux"

class App extends Component {
  render() {
    return (
      <div>
        你点击了<span id="value">{this.props.n}</span>次
      <div>
          <button id="add1" onClick={() => this.props.add1()}>+1</button>
          <button id="add2" onClick={() => this.props.add2()}>+2</button>
          <button id="addIfOdd" onClick={() => this.props.addIf()}>如果是单数就+1</button>
          <button id="add1After2Sec" onClick={() => this.props.add1After()}>两秒后+1</button>
        </div>
      </div>
    );
  }
}
function mapStateToProps(state) {
  return {
    n: state.n
  }
}
function mapDispatchToProps(dispatch) {
  return{
    add1: () => dispatch({ type: 'add', payload: 1 }),
    add2: () => dispatch({ type: 'add', payload: 2 }),
    add3: (oldState) => {
      if (oldState % 2 === 1) {
        dispatch({ type: 'add', payload: 1 })
      }
    },
    add4: () => {
      setTimeout(() => {
        dispatch({ type: 'add', payload: 1 })
      }, 2000)
    }
  }
  }
  
}
//这是一种写法,这是让一个函数接收两个参数,也就是要让这个函数return出一个函数就可以,见下方
// function connect(a){
//   console.log(a)
//   return function fn(b){
//       console.log(b)
//   }
// }
// connect(1)(2)
// function connect2(a){
//   return function fn(b){
//       console.log(a+b)
//   }
// }
// connect2(1)(2)
//也就是可以先接收一部分函数,再接收另一部分函数,其中connect(1)这半部分叫偏函数

export default connect(mapStateToProps, mapDispatchToProps)(App);
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容