Reac-redux 使用及其原理
Galloping_Leo 2021-03-31 React
# 使用
首先使用 Provider
包裹根组件向其中传递 store
,子组件可以通过 this.props
来获取 state
。
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import store from "./store";
import Counter from "./components/Counter";
ReactDOM.render(
<Provider store={store}>
<Counter />
</Provider>,
document.getElementById("root")
);
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
组件中使用 connect(mapStateToProps,mapDispatchTProps)(component)
函数,mapStateToProps
把状态数据映射到组件中,mapDispatchTProps
把 actions
绑定到组件中(内部使用的 bindActionsCreator
),可以使用 this.props
访问到。
import React, { Component } from "react";
import actions from "../store/actions/counter";
import { connect } from "react-redux";
class Counter extends Component {
render() {
console.log(this.props);
return (
<div>
<div>{this.props.number}</div>
<button onClick={this.props.increment}>+</button>
<button onClick={this.props.decrement}>-</button>
</div>
);
}
}
let mapStateToProps = (state) => state;
let mapDispatchTProps = actions;
export default connect(mapStateToProps, mapDispatchTProps)(Counter);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mapStateToProps
要映射的原因是:
- 状态树太大,但组件需要的很少,过滤状态。
- 可能需要修改或增加减少转态。
# 实现
import React from 'react'
export const ReduxContext = React.createContext()
1
2
2
import React, { Component } from 'react'
import { ReduxContext } from './context'
export default class Provider extend Component{
render(){
return (
<ReduxContext.Provider value={this.props.store}>
{this.props.children}
</ReduxContext.Provider>
)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
import React, { Component } from "react"
import { bindActionsCreators } from "../redux"
import { ReduxContext } from "./context"
export default (mapStateToProps, mapDispatchTProps) => {
return (Com) => {
return class Connect extends Component {
static contextType = ReduxContext
constructor(props, context) {
super(props)
this.state = mapStateToProps(context.getState())
}
componentDidMount() {
this.unsubscribe = this.store.subscribe(() => {
this.setState(mapStateToProps(this.store.getState()))
})
}
componentWillUnmount() {
this.unsubscribe()
}
render() {
this.store = this.context
let bindAxtions =
typeof mapDispatchTProps === "function"
? mapDispatchTProps(this.store.dispatch)
: bindActionsCreators(mapDispatchTProps, this.store.dispatch)
return <Com {...this.state} {...bindAxtions} />
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import connect from './connect'
import Provider from './provider'
export {Provider, connect}
1
2
3
4
2
3
4