# 面向初学者的高阶组件教程

## ES6 箭头函数简介

function () {
return 42}// 相当于:() => 42// 相当于:() => {    return 42}function person(name) {
return { name: name }
}// 相当于:(name) => {    return { name: name }
}

## 作为值的函数与部分调用

const execute = (someFunction) => someFunction()

const getOne = () => () => 1getOne()()

const getOne = () => () => 1getOne     //=> () => () => 1getOne()   //=> () => 1getOne()() //=> 1

const multiply = (x) => (y) => x * y

multiply(5)(20)

const multiply = (x) => (y) => x * y

multiply          //=> (x) => (y) => x * ymultiply(5)       //=> (y) => 5 * ymultiply(5)(20)   //=> 5 * 20

const multiply = (x) => (y) => x * yconst multiplyByFive = multiply(5)const multiplyBy100 = multiply(100)

multiplyByFive(20)  //=> 100multiply(5)(20)     //=> 100multiplyBy100(5)    //=> 500multiply(100)(5)    //=> 500

// before
const Button = styled.button`
background-color: \${({ theme }) => theme.bgColor}
color: \${({ theme }) => theme.textColor}
`<Button theme={themes.primary}>Submit</Button>// after
const fromTheme = (prop) => ({ theme }) => theme[prop]

const Button = styled.button`
background-color: \${fromTheme("bgColor")}
color: \${fromTheme("textColor")}
`<Button theme={themes.primary}>Submit</Button>

const fromTheme = (prop) => ({ theme }) => theme[prop]
const backgroundColor = fromTheme("bgColor")
const textColor = fromTheme("textColor")

const Button = styled.button`
background-color: \${backgroundColor}
color: \${textColor}
`<Button theme={themes.primary}>Submit</Button>

## 高阶函数

const square = (x) => x * x

[1, 2, 3].map(square)   //=> [ 1, 4, 9 ]

const map = (fn, array) => {    const mappedArray = []    for (let i = 0; i < array.length; i++) {
mappedArray.push(            // apply fn with the current element of the array
fn(array[i])
)
}    return mappedArray
}

const square = (x) => x * x

console.log(map(square, [1, 2, 3, 4, 5]))  //=> [ 1, 4, 9, 16, 25 ]

const HeroList = ({ heroes }) => (    <ul>
{map((hero) => (            <li key={hero}>{hero}</li>
), heroes)}    </ul>)<HeroList heroes=[
"Wonder Woman",
"Black Widow",
"Spider Man",
"Storm",
]/>/*=> (    <ul>
<li>Wonder Woman</li>
<li>Black Widow</li>
<li>Spider Man</li>
<li>Storm</li>
</ul>)*/

## 高阶组件

const Title = (props) => <h1>{props.children}</h1>ReactDOM.render(    <Title>Higher-Order Components(HOCs) for React Newbies</Title>,
document.getElementById('app')
)

// Technically an HOCconst ignore = (anything) => (props) => <h1>:)</h1>const IgnoreHeroList = ignore('HeroList')

ReactDOM.render(    <IgnoreHeroList />,
document.getElementById('app')
)

const yell = (PassedComponent) =>
({ children, ...props }) =>        <PassedComponent {...props}>
{children.toUpperCase()}!        </PassedComponent>const Title = (props) => <h1>{props.children}</h1>const AngryTitle = yell(Title)

ReactDOM.render(    <AngryTitle>Whatever</AngryTitle>,
document.getElementById('app')
)

const withGists = (PassedComponent) =>class WithGists extends React.Component {
state = {
gists: []
}

componentDidMount() {
fetch("https://api.github.com/gists/public")
.then((r) => r.json())
.then((gists) => this.setState({
gists: gists
}))
}

render() {        return (
<PassedComponent
{...this.props}
gists={this.state.gists}
/>
)
}
}const Gists = ({ gists }) => (
<pre>{JSON.stringify(gists, null, 2)}</pre>
)const GistsList = withGists(Gists)

<GistsList />// => Before api request finishes://  <Gists gists={[]} />//  // => After api request finishes://  <Gists gists={[//   { /* … */ },//   { /* … */ },//   { /* … */ }//  ]} />

withGists 会传递 gist api 调用的结果，并且你可以在任何组件上使用。点击这里 可以看到一个更加完整的例子。

## 结论：高阶组件是

react-redux 也是使用 HOC， connect 将应用 store 的值传递到“已连接” 的组件。它还会执行一些错误检查和组件生命周期优化，如果手动完成将导致编写大量重复代码。

HOCs 非常具有表现力，可以使用它们创造很多很酷的东西。

## 附加练习

• 写一个反转其输入的 HOC
• 编写一个HOC，将 API 中的数据提供给组件
• 写一个HOC来实现 shouldComponentUpdate，以避免更新。
• 编写一个 HOC，使用 React.Children.toArray 对传入组件子元素进行排序。

WEB前端性能优化常见方法

619 篇文章43 人订阅

0 条评论