Refs

通过 React.createRef() 创建 Ref

24Ref/App_1input.jsx

class MyInput extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }
  state = {
    inputValue: ''
  }
  inputFocus() {
    const oInput = this.inputRef.current;
    oInput.focus()
    this.setState({
      inputValue: ''
    })
  }
  changeInputValue(e) {
    this.setState({
      inputValue: e.target.value
    })
  }
  render() {
    return (
      <div>
        <input type="text"
          ref={ this.inputRef }
          value={ this.state.inputValue }
          onChange={ this.changeInputValue.bind(this) }
        />
        <button onClick={ this.inputFocus.bind(this) }>清空并聚焦</button>
        <br />
        <p>{ this.state.inputValue }</p>
      </div>
    )
  }
}
class App extends React.Component {
  render() {
    return (
      <MyInput />
    )
  }
}
ReactDOM.render(<App />, document.getElementById('app'));

将组件自身传递给外界(回调形式)

通过 props.onRef

App_5modal_dialog.jsx 01

class Modal extends React.Component {
  constructor(props) {
    super(props);
    this.modalRef = React.createRef();
    // 把自身传递给外界
    if (props.onRef) {
      props.onRef(this)
    }
  }
  open() {
    this.modalRef.current.style.display = 'block';
  }
  close() {
    this.modalRef.current.style.display = 'none';
  }
  render() {
    return (
      <div
        ref={ this.modalRef }
        style={{
          width: '300px',
          height: '300px',
          border: '1px solid #000',
          display: 'none'
        }}

      >
        <h1>modal dialog</h1>
        <p>This is a modal dialog</p>
      </div>
    )
  }
}
class App extends React.Component {
  modalOpen(status) {
    switch (status) {
      case 'open':
        this.modal.open();
        break;
      case 'close':
        this.modal.close();
        break;
      default:
        break;
    }
  }
  render() {
    return (
      <div>
				{ /* render 执行到下面代码时,把 instance 组件自身赋值给了 App 组件实例的 modal 属性 } */ }
        <Modal onRef={ instance => this.modal = instance } />
        <div>
          <button onClick={ this.modalOpen.bind(this, 'open') }>Open</button>
          <button onClick={ this.modalOpen.bind(this, 'close') }>Close</button>
        </div>
      </div>
    )
  }
}
ReactDOM.render(<App />, document.getElementById('app'));

或者

class Demo extends Component {
	inputRef = null
	render() {
		return (
			<input ref={ c => this.inputRef = c } />
		)
	}
}

当然除此以外,我们还可以利用 状态提升 而不是 refs 来将 modal 打开与否放进 App 中:

App_5modal_dialog.jsx 02

class Modal extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div
        style={{
          width: '300px',
          height: '300px',
          border: '1px solid #000',
          display: this.props.isOpen ? 'block' : 'none'
        }}

      >
        <h1>modal dialog</h1>
        <p>This is a modal dialog</p>
      </div>
    )
  }
}
class App extends React.Component {
  state = {
    isOpen: false
  }
  modalOpen(status) {
    this.setState({
      isOpen: status === 'open'
    })
  }
  render() {
    return (
      <div>
        <Modal isOpen={ this.state.isOpen } />
        <div>
          <button onClick={ this.modalOpen.bind(this, 'open') }>Open</button>
          <button onClick={ this.modalOpen.bind(this, 'close') }>Close</button>
        </div>
      </div>
    )
  }
}
ReactDOM.render(<App />, document.getElementById('app'));

React.createRef