Open zp1112 opened 6 years ago
在伟大的js中,高阶函数通俗的讲指的是一个参数为函数,且return返回值也是函数的函数,即:
const gjfunc = (func) => () => func(); // 定义一个高阶函数 const usegjfunc = gjfunc(() => {console.log(111)}) 调用高阶函数返回一个函数 usegjfunc(); // 使用这个函数
哇偶,好简单,高阶函数著名的应用就是柯里化.
const curry = (func, args) => { let len = func.length; args = args || []; return (...arg) => { args.push(...arg); if (args.length == len) { return func( ...args); } else { return curry(func,args); } } } curry((a, b) => a + b)(1)(2); // 3 const func1 = curry((a, b) => a + b); // 返回一个函数 const func2 = func1(1); // 返回一个函数 const func3 = func2(2); // 返回一个结果
高阶组件的概念通俗的讲就是一个参数为组件,返回值也是一个组件的函数, wrapperCom = wrapperFunc(wrappedComp);高阶组件 = 高阶函数(组件)
import React, { PureComponent } from 'react'; const WrapperFunc = (WrappedComp) => class WrapperFunc extends PureComponent { constructor(props) { super(props); this.state = { count: 0 } } render() { return ( <WrappedComp data = {this.state} {...this.props} /> )} } class wrappedComp extends PureComponent { render() { return( <div> {this.props.data.count} </div> )} } export const WrapperComp = WrapperFunc(wrappedComp);
这里的高阶函数WrapperFunc将wrappedComp组件包裹了一层,处理后再返回新的组件,实现了传入data属性来方便被包裹组件获得count公共状态,后面使用WrapperFunc包裹的任何组件都可以具备这个count。
那么如果我们想要定制count咋办呢,可以将count作为WrapperFunc函数的第二个参数,实现WrapperFunc(wrappedComp, 1)的功能,但是我们参考柯里化,可以使用更佳优雅的格式,将高阶函数再高阶一层,就变成了WrapperFunc(1)(wrappedComp),即WrapperFunc高阶函数,传入count=1作为参数,返回一个高阶函数,传入wrappedComp组件作为参数,返回包裹后的高阶组件。
import React, { Component, PureComponent } from 'react'; const WrapperFunc = (count) => (WrappedComp) => class WrapperFunc extends PureComponent { constructor(props) { super(props); this.state = { count } } render() { return ( <WrappedComp data = {this.state} {...this.props} /> )} } class wrappedComp extends PureComponent { render() { return( <div> {this.props.data.count} </div> )} } export const WrapperComp = WrapperFunc(1)(wrappedComp); export const WrapperComp1 = WrapperFunc(2)(wrappedComp);
用过react-redux的都知道,使用方式是这样滴:
<Provider store={store}> <App /> </Provider> // app.js class App extend PureComponent { // ... ] export default connect(mapStateToProp,mapDispatchToProp)(App); // 其中mapStateToProp,mapDispatchToProp两个函数分别实现了蒋store里面的state和dispatch转换成组件props里面的属性。
Provider 最核心的一点就是实现了store的向下传递,使用了React提供的API getChildContext方法和childContextText声明
import React, { Component } from 'react'; import PropTypes from 'prop-types'; export default class Provider extends Component { getChildContext() { return { store: this.props.store }; } render() { return this.props.children; } } Provider.childContextTypes = { store: PropTypes.object }
import React, { Component, PureComponent } from 'react'; import PropTypes from 'prop-types'; export default function connect(mapStateToProp, mapDispatchToProp) { return function(Comp) { class WrapperFunc extends PureComponent { constructor(props) { super(props); this.state = {} } componentDidMount() { this.setState({ ...this.state, ...mapStateToProp(this.context.store.getState()), ...mapDispatchToProp(this.context.store.dispatch) }) } render() { return ( <Comp {...this.state}/> ) } } WrapperFunc.contextTypes = { store: PropTypes.object } return WrapperFunc; } }
这里的关键步骤是将context里面的store里的state和dispatch传递给mapStateToProp, mapDispatchToProp这两个函数,这两个函数分别需要返回组件需要的状态和action,然后作为Comp组件的props传递下去。因此组件Comp就能在props中拿到store里面所需的东西。Boom!!!
import React from 'react'; import ReactDOM from 'react-dom'; import Provider from './provider'; import { createStore } from 'redux'; import App from './App'; import testStore from './testStore'; if (process.env.NOED_ENV !== 'production') { const { whyDidYouUpdate } = require('why-did-you-update'); whyDidYouUpdate(React); } const store = createStore(testStore); ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
App.js
import connect from './connect'; class App extends PureComponent { render() { return ( <div> {this.props.connectCount} </div> ); } } export default connect((state) =>({ connectCount: state.count }), (dispatch) => console.log(333, dispatch))(App);
大功告成,不知道该说啥,觉得自己对react的理解又通透了一些,开心~推荐图书《React进阶之路》
高阶函数
在伟大的js中,高阶函数通俗的讲指的是一个参数为函数,且return返回值也是函数的函数,即:
哇偶,好简单,高阶函数著名的应用就是柯里化.
高阶组件
高阶组件的概念通俗的讲就是一个参数为组件,返回值也是一个组件的函数, wrapperCom = wrapperFunc(wrappedComp);高阶组件 = 高阶函数(组件)
这里的高阶函数WrapperFunc将wrappedComp组件包裹了一层,处理后再返回新的组件,实现了传入data属性来方便被包裹组件获得count公共状态,后面使用WrapperFunc包裹的任何组件都可以具备这个count。
那么如果我们想要定制count咋办呢,可以将count作为WrapperFunc函数的第二个参数,实现WrapperFunc(wrappedComp, 1)的功能,但是我们参考柯里化,可以使用更佳优雅的格式,将高阶函数再高阶一层,就变成了WrapperFunc(1)(wrappedComp),即WrapperFunc高阶函数,传入count=1作为参数,返回一个高阶函数,传入wrappedComp组件作为参数,返回包裹后的高阶组件。
高阶组件应用在react-redux中的connect
用过react-redux的都知道,使用方式是这样滴:
实现一个简单的Provider
Provider 最核心的一点就是实现了store的向下传递,使用了React提供的API getChildContext方法和childContextText声明
实现一个简单的connect
这里的关键步骤是将context里面的store里的state和dispatch传递给mapStateToProp, mapDispatchToProp这两个函数,这两个函数分别需要返回组件需要的状态和action,然后作为Comp组件的props传递下去。因此组件Comp就能在props中拿到store里面所需的东西。Boom!!!
使用自己的connect和Provider
App.js
大功告成,不知道该说啥,觉得自己对react的理解又通透了一些,开心~推荐图书《React进阶之路》