前言
- 很是感谢小伙伴的支持和鼓励,从博客园转战到掘金,没想到获得这么多的小伙伴的支持,在此表示十分的感谢,大家鼓励我是写详细注释的教程的巨大动力
- 今天为你们带来,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')
)
复制代码
结语
系列文章