前言
- 很是感謝小夥伴的支持和鼓勵,從博客園轉戰到掘金,沒想到獲得這麼多的小夥伴的支持,在此表示十分的感謝,大家鼓勵我是寫詳細註釋的教程的巨大動力
- 今天爲你們帶來,react-redux的詳細教程
- 沒有用腳手架,手動配置webpack各類配置文件,以一個計數器的案例來講明
- 重要的事說三遍,註釋,註釋,詳細註釋
- react-redux 我就不介紹了,直接上代碼(愛都在代碼裏)
案例搭建
const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: path.join(__dirname, './src/main.js'),
output: {
path: path.join(__dirname, './dist'),
filename: 'bundle.js'
},
devServer: {
open: true,
port: 3000,
proxy: {
'/api': {
target: 'https://api.douban.com/v2',
secure: false,
changeOrigin: true,
pathRewrite: { '^/api': '' }
}
}
},
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.(png|jpg|jpeg|gif)$/, use: 'url-loader' },
{ test: /\.js/, use: 'babel-loader', exclude: /node_modules/ }
]
},
plugins: [
new htmlWebpackPlugin({
template: path.join(__dirname, './src/index.html')
})
]
}
複製代碼
- redux的基本概念,和vue的vuex的思想相似,狀態管理。屬於換湯不換藥
複製代碼
import { createStore } from 'redux'
const counter = (state = 0, action) => {
console.log(state, action)
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const increment = () => ({
type: 'INCREMENT'
})
const decrement = () => ({
type: 'DECREMENT'
})
const store = createStore(counter)
console.log('獲取狀態:', store.getState())
store.dispatch(increment())
console.log('新狀態爲:', store.getState())
複製代碼
import { createStore } from 'redux'
const counter = (state = 0, action) => {
console.log(state, action)
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const increment = () => ({
type: 'INCREMENT'
})
const decrement = () => ({
type: 'DECREMENT'
})
const store = createStore(counter)
const unsubscribe = store.subscribe(() => {
console.log('新狀態爲:', store.getState())
})
console.log('獲取狀態:', store.getState())
store.dispatch(increment())
store.dispatch(increment())
unsubscribe()
store.dispatch(increment())
複製代碼
import { createStore } from 'redux'
import React from 'react'
import ReactDOM from 'react-dom'
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const increment = () => ({
type: 'INCREMENT'
})
const decrement = () => ({
type: 'DECREMENT'
})
const store = createStore(counter)
store.subscribe(() => {
render()
})
const Counter = () => (
<div> <h1> 當前值: {store.getState()} </h1> <button onClick={() => store.dispatch(increment())}>+1</button> <button onClick={() => store.dispatch(decrement())}>-1</button> </div>
)
const render = () => {
ReactDOM.render(<Counter />, document.getElementById('app')) } render() 複製代碼
- class組件forceUpdate更新state
import { createStore } from 'redux'
import React from 'react'
import ReactDOM from 'react-dom'
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const increment = () => ({
type: 'INCREMENT'
})
const decrement = () => ({
type: 'DECREMENT'
})
const store = createStore(counter)
class Counter extends React.Component {
componentDidMount() {
this.unsubscribe = this.props.store.subscribe(() => {
this.forceUpdate()
})
}
componentWillUnmount() {
this.unsubscribe()
}
render() {
const { store } = this.props
return (
<div> <h1> 當前值: {store.getState()} </h1> <button onClick={() => store.dispatch(increment())}>+1</button> <button onClick={() => store.dispatch(decrement())}>-1</button> </div>
)
}
}
ReactDOM.render(<Counter store={store} />, document.getElementById('app')) 複製代碼
import { createStore } from 'redux'
import React from 'react'
import ReactDOM from 'react-dom'
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const increment = () => ({
type: 'INCREMENT'
})
const decrement = () => ({
type: 'DECREMENT'
})
const store = createStore(counter)
class Counter extends React.Component {
componentDidMount() {
this.unsubscribe = this.props.store.subscribe(() => {
this.forceUpdate()
})
}
componentWillUnmount() {
this.unsubscribe()
}
render() {
const { store } = this.props
return (
<div> <h1> 當前值: {store.getState()} </h1> <button onClick={() => store.dispatch(increment())}>+1</button> <button onClick={() => store.dispatch(decrement())}>-1</button> </div>
)
}
}
ReactDOM.render(<Counter store={store} />, document.getElementById('app')) 複製代碼
import { createStore } from 'redux'
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider, connect } from 'react-redux'
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const increment = () => ({
type: 'INCREMENT'
})
const decrement = () => ({
type: 'DECREMENT'
})
const store = createStore(counter)
store.subscribe(() => {
console.log('state: ', store.getState())
})
const Counter = props => {
console.log('Counter 組件props:', props)
const { dispatch, count } = props
return (
<div> <h1> 當前值: {count} </h1> <button onClick={() => dispatch(increment())}>+1</button> <button onClick={() => dispatch(decrement())}>-1</button> </div>
)
}
const mapStateToProps = state => {
console.log('mapStateToProps:', state)
return {
count: state
}
}
const CounterContainer = connect(mapStateToProps)(Counter)
ReactDOM.render(
<Provider store={store}> <CounterContainer /> </Provider>,
document.getElementById('app')
)
複製代碼
import { createStore } from 'redux'
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider, connect } from 'react-redux'
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const increment = () => ({
type: 'INCREMENT'
})
const decrement = () => ({
type: 'DECREMENT'
})
const store = createStore(counter)
store.subscribe(() => {
console.log('state: ', store.getState())
})
const Counter = props => {
console.log('Counter 組件props:', props)
const { dispatch, count } = props
return (
<div> <h1> 當前值: {count} </h1> <button onClick={() => dispatch(increment())}>+1</button> <button onClick={() => dispatch(decrement())}>-1</button> </div>
)
}
const mapStateToProps = state => {
return {
count: state
}
}
const CounterContainer = connect(mapStateToProps)(Counter)
ReactDOM.render(
<Provider store={store}>
<CounterContainer /> </Provider>,
document.getElementById('app')
)
複製代碼
- react-redux中mapDispatchToProps的使用
import { createStore } from 'redux'
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider, connect } from 'react-redux'
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const increment = () => ({
type: 'INCREMENT'
})
const decrement = () => ({
type: 'DECREMENT'
})
const store = createStore(counter)
store.subscribe(() => {
console.log('state: ', store.getState())
})
const Counter = props => {
console.log('Counter 組件props:', props)
const { count, onIncrement, onDecrement } = props
return (
<div> <h1> 當前值: {count} </h1> <button onClick={onIncrement}>+1</button> <button onClick={onDecrement}>-1</button> </div>
)
}
const mapStateToProps = state => {
return {
count: state
}
}
const mapDispatchToProps = dispatch => {
return {
onIncrement() {
dispatch(increment())
},
onDecrement() {
dispatch(decrement())
}
}
}
const CounterContainer = connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
ReactDOM.render(
<Provider store={store}>
<CounterContainer /> </Provider>,
document.getElementById('app')
)
複製代碼
結語
系列文章