Provider:把store注册到上下文中
import store from './store'
import { Provider } from 'react-redux'
root.render(
<Provider store={store}>
<Vote />
</Provider>
)
connect:把公共状态和派发任务当做属性传递给属性
-
自动获取上下文中的store
-
自动把让组件更新的方法注册到store事件池中
-
mapStateToProps
-
mapDispatchToProps
import { connect } from 'react-redux'
const Vote = function Vote(props) {
let { supNum, oppNum } = props
return <div className="vote-box">...</div>
}
export default connect((state) => {
return state.vote
})(Vote)
import actions from '@/store/actions'
import { connect } from 'react-redux'
const VoteFooter = function VoteFooter(props) {
let { support, oppose } = props
return (
<div className="footer">
<button onClick={support}>支持</button>
<button onClick={oppose}>反对</button>
</div>
)
}
export default connect(
null,
(dispatch) => {
return {
support() {
dispatch(actions.vote.support(10))
},
oppose() {
dispatch(actions.vote.oppose())
}
}
}
)(VoteFooter)
// 或者
<button onClick={support.bind(null, 10)}>支持</button>
export default connect(
null,
actions.vote
)(VoteFooter)
react-redux源码
import {
createContext,
useContext,
useLayoutEffect,
useMemo,
useState
} from 'react'
import { bindActionCreators } from 'redux'
// 创建上下文对象
const ThemeContext = createContext()
// Provider
export function Provider(props) {
return (
<ThemeContext.Provider
value={{
store: props.store
}}
>
{props.children}
</ThemeContext.Provider>
)
}
// connect
export function connect(mapStateToProps, mapDispatchToProps) {
if (!mapStateToProps) {
mapStateToProps = function mapStateToProps() {
return {}
}
}
if (!mapDispatchToProps) {
mapDispatchToProps = function mapDispatchToProps() {
return {}
}
}
return function HOC(Component) {
return function Proxy(props) {
let { store } = useContext(ThemeContext),
{ getState, dispatch, subscribe } = store
// 处理状态
let state = getState()
state = useMemo(() => mapStateToProps(state), [state])
// 处理任务派发
let dispatchToProps = useMemo(() => {
if (typeof mapDispatchToProps === 'function') {
return mapDispatchToProps(dispatch)
}
return bindActionCreators(mapDispatchToProps, dispatch)
}, [dispatch])
// 向事件池注入方法
const [, forceUpdate] = useState(0)
useLayoutEffect(() => {
return subscribe(() => forceUpdate(+new Date()))
}, [subscribe])
return <Component {...props} {...state} {...dispatchToProps} />
}
}
}