Day4使用react+redux來重構(gòu)代碼
三種:
- 原生js+redux
- js變成了react(ReactDOM.render那部分)
- react-redux
其中1、2的區(qū)別是:1是整個div刷新,2是只刷新{this.props.value}(利用dom diff)
那么
為什么要使用react-redux ,一起來看看三個版本的比較與差異
!版本1----App.js無法直接用store,而是要用this.props一層一層的往上調(diào)用store
!版本2----可以直接使用store,但是要獲取store要一層一層的往下傳,每個組件都要傳store={this.props.store}
!版本3----react-redux重構(gòu)
代碼如下:
版本1----App.js無法直接用store,而是要用this.props一層一層的往上調(diào)用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()}>如果是單數(shù)就+1</button>
<button id="add1After2Sec" onClick={()=>this.add1After()}>兩秒后+1</button>
</div>
</div>
);
}
}
export default App;
關于箭頭函數(shù):
1.函數(shù)不需要傳參
store.subscribe(()=>{
render()
})//等價于store.subscribe(render)
注意:我們是將函數(shù)作為參數(shù)傳給subscribe,而不是將函數(shù)值傳給subscribe
如果改變一下寫法:
store.subscribe(render())//這種就是將render函數(shù)的函數(shù)值傳給了subscribe,就會報錯
2.函數(shù)需要傳參
A.b(()=>{
c(d)
})
注意:如果我要傳的函數(shù)有參數(shù),就一定要使用箭頭函數(shù)
react比原生js好的地方就是:不需要整體更新div,而是可以根據(jù)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()}>如果是單數(shù)就+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
//根據(jù)舊的state產(chǎn)生新的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()}>如果是單數(shù)就+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)
}
}
}
}
//這是一種寫法,這是讓一個函數(shù)接收兩個參數(shù),也就是要讓這個函數(shù)return出一個函數(shù)就可以,見下方
// 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)
//也就是可以先接收一部分函數(shù),再接收另一部分函數(shù),其中connect(1)這半部分叫偏函數(shù)
export default connect(mapStateToProps, mapDispatchToProps)(App);