面试官:你说你开发过组件库,那你怎么会不知道受控组件?面试就到这里吧。我:😭

8,426 阅读3分钟

前端开发到底在开发什么?可以说就是在做 Form 组件的开发,而受控组件又是其中的重中之重,了解了受控组件才能算真正的懂前端

🤖 什么是受控组件?

  1. 就是如果你传入了受控属性,比如传入一个受控属性 value<MyInput value={value} onChange={handleChange}/>

  2. 那么你和组件进行交互,他自己内部就不处理了,只是把值给到你传入的 onChange,让你来决定怎么做,受你的控制,要不要让我 MyInput 重渲染是你的事情,我MyInput 不管了

function App() {
  const [value, setValue] = useState('')
  function handleChange(val) {
    setValue(val)
  }
  return <MyInput value={value} onChange={handleChange} />
}

我来实现一个简单的受控组件 <MyInput/>

function MyInput(props) {
  const [value, setValue] = useControllableValue(props)
  function handleChange(e) {
    // currentTarget,当前触发 onChange 事件的那一个组件
    const value = e.currentTarget.value
    setValue(value)
  }
  return <input value={value} onChange={handleChange} />
}

这个组件具体做了什么呢?

  1. 给原生的 input 绑定了 value 和 onChange 事件 原生标签 input、button 加了 value 直接就变成受控组件,react 官网有说明
  2. 那么当你在 <input /> 输入的时候,输入框永远不会变是空白的,他只会触发 <input onChange={handleChange} /> 事件
  3. handleChange里面,我们调用了 setValue(value)

这个就是精髓,他是封装过的 setValue

  1. setValue 如果发现你是这么用的 <MyInput value={value} onChange={handleChange}/>,也就是传了一个 value 属性给到 <MyInput />

  2. 这个 setValue 他在内部并不会 setState,只是把参数传给了处理事件而已 <MyInput onChange={handleChange}/>

🤖 setValue 做了什么?

const [value, setValue] = useControllableValue(props)

这个 valueuseControllableValue 内部其实也是用 useState 创建的

  1. 他会读取 <MyInput /> 组件的 props,看看 props 上有没有 value 字段
  2. 如果没有 value 字段,你去执行 setValue(val)useControllableValue 内部就会通过 setState(val) 去修改 value,那么用到 useControllableValue 这个组件就会重渲染。
    并且还会把最新值给到 props上的 onChange 函数执行
  3. 如果有 value 字段,你去执行 setValue(val),他只会把值 val 给到 props 上的 onChange 函数而已,就不会 setState 了,所以什么也没发生

useControllableValue 默认读取 props.valueprops.onChange,当然可以自定义,去看 ahooks 文档

🤖 那么您想想看,Form 组件是怎么利用这些受控组件的?

  1. 简单嘛,里面肯定就是封装了一个 class 实例来管理这些表单项
  2. 先将每个表单项都变成受控组件方便我实例来管理
    也就是给每一个表单项传递一个 valueonChange
  3. 这样,你去修改这些受控的表单项,他自己什么都不做,但是会把最新值给到 onChange,你在 onChange 函数里面不是想干什么就干什么了吗?🥵

🤖 相关

面试官:你说你做过组件库,肯定了解过复杂组件状态管理的useSyncExternalStore吧?我:😭

面试官:你跟我说 setState 是同步的,它不是异步的吗?背错面试题了吧你!我:😭

面试官:你说你开发过组件库,那你怎么会不知道受控组件?面试就到这里吧。我:😭

版权归许泽川所有

如需转载,请提前询问本人的许可