1. 函数式组件和类组件区别
- 函数式组件
函数式组件是一种简单的组件定义方式,它是一个以JavaScript函数为基础的组件。
可以把函数式组件理解为纯函数,它的输入为props,输出为JSX。函数式组件没有状态,也没有生命周期。
function List(props){
const {list} = this.props
return <ul>
{
list.map((item, index) => {
return <li key={item.id}>
<span>{item.title}</span>
</li>
})
}
</ul>
}
- 类组件
类组件是React中的早期概念,它通过继承React.Component类来创建。类组件在React的生命周期和状态管理方面具有更多的控制权。
class List extends React.Component{
constructor(props){
super(props)
}
render(){
const {list} = this.props
return <ul>
{
list.map((item, index) => {
return <li key={item.id}>
<span>{item.title}</span>
</li>
})
}
</ul>
}
}
2. 非受控组件
非受控组件:通过在组件在传入ref属性,然后通过ref属性拿到当前组件的DOM节点,通过DOM节点拿到当前组件的值。通过这种方式拿到的组件的值,是不受组件的状态控制的。这种组件称为“非受控组件”。
- 以下代码示例中,alert中的提示信息为input标签DOM元素中的值,而不是状态中的值。
class App extends React.Component{
constructor(props) {
super(props)
this.state = {
name: '小白',
}
this.nameInputRef = React.createRef() // 通过React.createRef()方法创建ref
}
alertName = () => {
const elem = this.nameInputRef.current // 通过 ref 获取 DOM 节点
alert(elem.value) // 不是state的值,而是从DOM元素中取得的值
}
render(){
return(
<div>
<input defaultValue={this.state.name} ref={this.nameInputRef}/>
<span>state.name: {this.state.name}</span>
<br/>
<button onClick={this.alertName}>alert name</button>
</div>
)
}
}
- 非受控组件的使用场景:必须手动操作DOM元素,只更改组件的状态无法实现目的。例如文件上传,因为文件的相关信息必须通过DOM元素的
files
属性获取。
class App extends React.Component{
constructor(props) {
super(props)
this.fileInputRef = React.createRef() // 通过React.createRef()方法创建ref
}
alertFile = () => {
const elem = this.fileInputRef.current // 通过 ref 获取 DOM 节点
alert(elem.files[0].name) // 打印上传的文件的名字
}
render(){
return(
<div>
<input type="file" ref={this.fileInputRef}/>
<button onClick={this.alertFile}>alert file</button>
</div>
)
}
}