自己實現React-Redux
阿新 • • 發佈:2018-11-24
React-Redux核心
React-Redux核心API:
Redux 官方提供的 React 繫結庫。具有高效且靈活的特性。
- Provider 元件
用於在應用頂層提供store。 - connect 函式
用於給元件提供store的狀態和dispatch方法。接收四個引數,返回一個高階元件。
逐步程式碼實現(涉及ES6和JSX語法):
Provider
1、首先Provider是一個頂層容器元件,接收一個store引數:
import React from 'react';
import PropTypes from 'prop-types';
export default class Provider extends React.Component {
static propTypes = {
store: PropTypes.object.isRequired
}
render(){
return this.props.children;
}
}
2、將store掛載到context上,以便讓子元件訪問到:
import React from 'react'; import PropTypes from 'prop-types'; export default class Provider extends React.Component { static propTypes = { store: PropTypes.object.isRequired } /* 新增程式碼 */ getChildrenContext(){ return { store: this.props.store}; } * *********** */ render(){ return this.props.children; } }
可以看到,Provider的實現非常簡單。
connect
connect的實現比較複雜,它應接收四個引數:
mapStateToProps
回撥函式,接收當前的state作為引數,返回一個物件作為元件的引數;mapDispatchToProps
回撥函式,接收store的dispatch方法作為引數,返回值同上;mergeProps
回撥函式,接收前兩個函式的返回值以及元件本身的引數作為引數,返回值作為傳遞給元件的最終的引數。options
配置項,暫且不管。
1、connect大概的樣子:
它接收三個引數,返回一個高階元件。
import React from 'react';
import PropTypes from 'prop-types';
const connect = (
mapStateToProps,
mapDispatchToProps,
mergeProps
) => {
const withConnect = Comp =>
class CompWithConnect extends React.Component{
render(){
const finalProps = this.props;
return <Comp { ...finalProps } />
}
};
return withConnect;
};
export default connect;
2、先讓元件獲取store,並獲取所需的state及dispatch方法:
import React from 'react';
import PropTypes from 'prop-types';
const connect = (
mapStateToProps,
mapDispatchToProps,
mergeProps
) => {
const withConnect = Comp =>
class CompWithConnect extends React.Component{
/* 新增程式碼 */
static contextTypes = {
store: PropTypes.object
}
/* ********** */
render(){
/* 新增程式碼 */
const currentState = this.context.store.getState();
const dispatch = this.context.store.diaptch;
/* ********** */
const finalProps = this.props;
return <Comp { ...finalProps } />
}
};
return withConnect;
};
export default connect;
3、考慮到引數是可選的,應提供三個方法的預設值:
import React from 'react';
import PropTypes from 'prop-types';
/* 新增程式碼 */
const defaultMapStateToProps = () => ({});
const defaultMapDispatchToProps = () => ({});
const defaultMergeProps = (
mappedStateProps,
mappedDipatchProps,
ownProps
) => ({
...ownProps,
...mappedStateProps,
...mappedDipatchProps
});
/* ********** */
const connect = (
mapStateToProps,
mapDispatchToProps,
mergeProps
) => {
/* 新增程式碼 */
const finalMapStateToProps = mapStateToProps||defaultMapStateToProps;
const finalMapDispatchToProps = mapDispatchToProps||defaultMapDispatchToProps;
const finalMergeProps = mergeProps||defaultMergeProps;
/* ********** */
const withConnect = Comp =>
class CompWithConnect extends React.Component{
static contextTypes = {
store: PropTypes.object
}
render(){
const currentState = this.context.store.getState();
const dispatch = this.context.store.diaptch;
const finalProps = this.props;
return <Comp { ...finalProps } />
}
};
return withConnect;
};
export default connect;
4、計運算元元件的引數:
import React from 'react';
import PropTypes from 'prop-types';
const defaultMapStateToProps = () => ({});
const defaultMapDispatchToProps = () => ({});
const defaultMergeProps = (
mappedStateProps,
mappedDipatchProps,
ownProps
) => ({
...ownProps,
...mappedStateProps,
...mappedDipatchProps
});
const connect = (
mapStateToProps,
mapDispatchToProps,
mergeProps
) => {
const finalMapStateToProps = mapStateToProps||defaultMapStateToProps;
const finalMapDispatchToProps = mapDispatchToProps||defaultMapDispatchToProps;
const finalMergeProps = mergeProps||defaultMergeProps;
/* 新增程式碼 */
const computedProps = (currentState, dispatch, ownProps) => finalMergeProps(finalMapStateToProps(currentState), finalMapDispatchToProps(dispatch), ownProps);
/* ********** */
const withConnect = Comp =>
class CompWithConnect extends React.Component{
static contextTypes = {
store: PropTypes.object
}
render(){
const currentState = this.context.store.getState();
const dispatch = this.context.store.diaptch;
/* 修改程式碼 */
const finalProps = computedProps(currentState, dispatch, this.props);
/* ********** */
return <Comp { ...finalProps } />
}
};
return withConnect;
};
export default connect;