- 非受控组件
把input看作一个组件,此时的input则为一个非受控组件,input内部的value属性为input内部所控制,虽然可以通过ref来进行取值与赋值操作,但是在input输入框值发生改变时无法让父组件调用render()函数来进行重新渲染。
import ReactDOM from 'react-dom/client';
import React, { Component } from 'react'
class Ikun1 extends Component {
myRef = React.createRef()
render() {
return (
<>
<input ref={this.myRef} defaultValue="九转大肠" />
<button onClick={() => { console.log(this.myRef.current.value) }} >获取input的值</button>
<button onClick={() => { this.myRef.current.value = '我是故意的' }}>给input设置</button>
<Ikun2 />
{/* <Ikun2 inputValue={this.myRef.current.value} /> */}
</>
)
}
}
class Ikun2 extends Component {
render() {
return (
<div>我接收到了:{this.props.inputValue}</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Ikun1 />
);
当你想监听input的value值变化时,通过this.myRef.current.value,是无法单纯地进行传值给其它组件,如下会直接报错
因为一开始父组件reader执行一次,后面便没有再次更新this.myRef的值,所以this.myRef为空
- 受控组件
为了能够监听input里面的值,将上面的代码改成如下:
import ReactDOM from 'react-dom/client';
import React, { Component } from 'react'
class Ikun1 extends Component {
myRef = React.createRef()
state={
inputValue:''
}
render() {
return (
<>
<input ref={this.myRef} defaultValue="九转大肠" onChange={(event)=>{this.fix(event)}}/>
<button onClick={() => { console.log(this.myRef.current.value) }} >获取input的值</button>
<button onClick={() => { this.myRef.current.value = '我是故意的' }}>给input设置</button>
<Ikun2 inputValue={ this.state.inputValue } />
</>
)
}
fix(event){
this.setState({
inputValue:event.target.value
},()=>{console.log(this.state.inputValue)})
}
}
class Ikun2 extends Component {
render() {
return (
<div>我接收到了:{this.props.inputValue}</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Ikun1 />
);
通过父组件的state,setState,与input的onChange,即可实现让<Ikun2>这个组件监听到input输入框value值的变化。
此时,既然都使用了父组件的state,那就没有必要再绕一层ref了,修改如下:
import ReactDOM from 'react-dom/client';
import React, { Component } from 'react'
class Ikun1 extends Component {
state = {
inputValue: ''
}
render() {
return (
<>
<input onChange={(event)=>{this.setState({ inputValue: event.target.value })}} value={this.state.inputValue}/>
<button onClick={() => { console.log(this.state.inputValue) }} >获取input的值</button>
<button onClick={()=>this.setState({ inputValue: '我是故意的' })} >给input设置</button>
<Ikun2 inputValues={this.state.inputValue} />
</>
)
}
}
class Ikun2 extends Component {
render() {
return (
<div>我接收到了:{this.props.inputValues}</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Ikun1 />
);
此时,input内的value属性由父组件控制,input变成了受控组件