useRef
useRef有點類似Vue中的ref,用來存取實際DOM元素,可以參考官網的解說。
useRef、forwardRef
這邊使用useRef、forwardRef來存取子元件DOM。
//父元件 form
import { useRef } from 'react'
import classes from './MealItemForm.module.css'
import Input from '../../UI/Input'
const MealItemForm = (props)=>{
  const amountInputRef = useRef()
  const submitHandler = event=>{
    event.preventDefault()
  }
  return (
  <form className={classes.form} onSubmit={submitHandler}>
    <Input
      ref={amountInputRef}
      label={'Amount'}
      input={{
        id:  'amount_' + props.id,
        type:"number",
      }}
    />
    <button>+ Add</button>
  </form>
  )
}
export default MealItemForm
子元件使用forwardRef讓父元件可以取到子元件的DOM,子元件的參數除了props,會在多接收一個ref的參數。
import React from 'react'
import classes from './Input.module.css'
const Input = React.forwardRef((props, ref)=>{
  return (
    <div className={classes.input}>
      <label htmlFor={props.input.id}>{props.label}</label>
      <input {...props.input} ref={ref}></input>
    </div>
  )
})
export default Input
useImperativeHandle
useImperativeHandle可以從子元件傳遞自定義內容。使用方式必須和useRef、forwardRef一起使用。
import React {useImperativeHandle, forwardRef, useRef}from 'react'
import classes from './Input.module.css'
const Input = forwardRef((props, ref)=>{
const inputRef = useRef()
const activate = ()=> {
    inputRef.current.focus()
}
useImperativeHandle(ref, ()=>{
    focus: activate
})
  return (
    <div className={classes.input}>
      <label htmlFor={props.input.id}>{props.label}</label>
      <input {...props.input} ref={ref}></input>
    </div>
  )
})
export default Input
父元件就可以透過綁定的ref去取到子元件剛剛給他的focus函式。
//父元件 form
import { useRef } from 'react'
import classes from './MealItemForm.module.css'
import Input from '../../UI/Input'
const MealItemForm = (props)=>{
  const amountInputRef = useRef()
  const submitHandler = event=>{
    event.preventDefault()
    amountInputRef.current.focus()
  }
  return (
  <form className={classes.form} onSubmit={submitHandler}>
    <Input
      ref={amountInputRef}
      label={'Amount'}
      input={{
        id:  'amount_' + props.id,
        type:"number",
      }}
    />
    <button>+ Add</button>
  </form>
  )
}
export default MealItemForm


