react受控与非受控

  • 非受控组件

把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变成了受控组件

猜你喜欢

转载自blog.csdn.net/qq_46149597/article/details/129218864