高阶组件
高阶组件指的不是组件,而是一个函数,它可以增强组件,它接收一个组件,返回一个新组件,这个新组件是接收组件的加强版。假设有这样三个组件
class App1 extends React.Component {
state = { data: null };
componnetDidMount() {
const data = localStorage.getItem("data");
this.setState({
data
});
}
render() {
return <div>{this.state.data}</div>;
}
}
class App2 extends React.Component {
state = { data: null };
componnetDidMount() {
const data = localStorage.getItem("data");
this.setState({
data
});
}
render() {
return <div>{this.state.data}</div>;
}
}
class App3 extends React.Component {
state = { data: null };
componnetDidMount() {
const data = localStorage.getItem("data");
this.setState({
data
});
}
render() {
return <div>{this.state.data}</div>;
}
}
观察这三个组件,它们都有一个共同的特点,那就是它们在挂载后都要从localStorage中获取数据,可见这样的代码是重复了的,我们如果每次要从localStorage获取数据,都要写一遍这样的代码,那怎么可以让这样的逻辑复用呢? 这就是高阶组件的作用,考虑下面这样的一个函数
function getDataFromLocalStorage(WrapComponent) {
class NewComponent extends React.Component {
state = { data: null };
componentDidComponent() {
const data = localStorage.getItem("data");
this.setState({
data
});
}
render() {
return <WrapComponent data={this.state.data} />
}
}
return NewComponent
}
该函数接收一个组件,返回一个新组件。这个新组件在挂载后会用localStorage读取数据,并注入到传入的组件的props.data中。而这个传入的组件会作为新组件render函数的返回值,所以当我们使用这个新组件时,与使用传入的组件一致,不过此时新组件的props中已经有了从localStorage读取的数据。我们可以将上面的三个组件都可以改造为
class App1 extends React.Component {
render() {
return <div>{this.props.data}</div>
}
App1 = getDataFromLocalStorage(App1)
}
class App2 extends React.Component {
render() {
return <div>{this.props.data}</div>
}
App2 = getDataFromLocalStorage(App2)
}
class App3 extends React.Component {
render() {
return <div>{this.props.data}</div>
}
App3 = getDataFromLocalStorage(App3)
}
我们使用高阶函数为三个组件的props.data中注入了数据,这样三个组件只要调用这个方法,就可以自动可以在props中获取到数据,从而达到了代码的复用。可能读到这里你还不能理解,没关系,多读几遍好好消化,或者写个几遍就习惯了。
render props
render props的目的同样也是进行代码的复用。再次考虑上面代码的复用,不过这次使用render props实现代码的复用
class GetDataFromLocalStorage extends React.Component {
state = {data: null}
componentDidMount() {
this.setState(localStorage.getItem("data"))
}
render() {
return {this.props.render(this.state)}
}
}
class App extends React.Component {
render() {
return (
<GetDataFromLocalStorage
render = {({data}) => {
return <div>data</div>
}}
/>
)
}
}
仔细阅读上面的代码,想必还是比较容易读懂的。Render Props的核心思想是,通过一个函数将class组件的state作为props传递给纯函数组件。