高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。
我在之前的博客《闭包和类》中提到一个观点,面向对象的好处就在于,易于理解,方便维护和复用。
其实高阶组件,也是为了更好地复用之前的组件。它可以理解为,基础组件通过包裹处理,生成一个适应某些场景的组件。
它可能存在于以下几种场景:
一个简单例子:
function withMoreThings(WrappedComponent) { return class extends React.Component { render() { const moreThings = { more: 'things', }; return <WrappedComponent {...this.props} ...moreThings/> } } }这是HOC(High Order Component)最常用的一种方式,用来传递一些定制化的参数给内部组件。
提取公共方法、属性在to B的项目中,表单是一个大头,所有流程都绕不开表单。也就会说到受控组件和非受控组件。
受控组件由于HTML表单元素会保留一些内部状态,比如input框,它会有自己内部的状态来保存用户的输入值。
<input type="text" />此时,为了能够处理将React的state和表单元素的内部状态统一起来,React提供了一种称为“受控组件”的技术。
class NameInput extends React.Component { constructor(props) { super(props); this.state = {value: ''}; this.handleChange = this.handleChange.bind(this); } handleChange(event) { console.log(this); this.setState({value: event.target.value}); } render() { return ( <input type="text" value={this.state.value} onChange={this.handleChange} /> ); } }通过内部的state和绑定change事件,就可以将input内部的处理机制转移到React的默认处理机制上,收到React的控制。
但是,还是有一些元素,不能使用这种方法,比如
这个元素是只读的,用户选择完毕后,可以获取到对应的文件。不能通过React内部的state来模拟。
这就引出了——
非受控组件从DOM中获取表单值,而不是通过React的state来处理。由于它不经过React的一些逻辑,所以不能对它的状态做监控。这里有一篇文章Controlled and uncontrolled form inputs in React don't have to be complicated介绍了何时可以使用非受控组件。
下面是一个非受控组件的例子:
和 支持 defaultChecked,