react render propsGetter

RobinsonZhang發表於2019-02-23

前言

通過上篇的介紹,我們可以把一些常見的屬性封裝到一個輔助方法裡,讓我們對這部分的使用更加方便。

但這樣並不是非常的完美,因為有些時候我們需要獲取其部分屬性,還有部分場景下可以追加自己的事件。

獲取設定屬性

比如之前的案例中,我們在toggle元件使用中,針對on屬性需要顯性的作為入參才可以使用,追加的onclick事件不但希望觸發toggle事件,也希望可以進行自定義事件的觸發

function Usage({
  onToggle = (...args) => console.log(`onToggle`, ...args),
}) {
  return (
    <Toggle onToggle={onToggle}>
      {({on, togglerProps}) => (
        <div>
          <Switch on={on} {...togglerProps} />
          <hr />
          <button aria-label="custom-button" {...togglerProps}>
            {on ? `on` : `off`}
          </button>
        </div>
      )}
    </Toggle>
  )
}
複製程式碼

將屬性進行封裝,事件的部分進行封裝

增加額外獲取屬性方法

 getStateAndHelpers() {
    return {
      on: this.state.on,
      toggle: this.toggle,
// 增加額外的屬性 用於給函式的子元件方便獲取任意需要的屬性
      getTogglerProps: this.getTogglerProps,
    }
  }
複製程式碼

定義getTogglerProps方法

不僅要考慮到封裝好所有的props屬性,也要封裝其他的需要屬性,比如aria-pressed的屬性,以及對特殊OnClick進行事件的繫結,與此同時也讓其觸發toggle原本的方法

getTogglerProps = ({onClick,className, ...props} = {}) => ({
    `aria-pressed`: this.state.on,
    onClick: callAll(onClick, this.toggle),
// 如果你想新增額外的className進行支援  在其傳入時 進行新增
className:`${className} our-custom-class-name`
    ...props,
  })
複製程式碼

定義callAll 方法 執行

需要額外注意的是,前面要追加fn &,因為追加的事件是需要顯性定義然後才執行的,而如果是toogle本身的點選是不需要定義點選事件的,直接執行事件會報錯。

const callAll = (...fns) => (...args) =>
  fns.forEach(fn => fn && fn(...args))
複製程式碼

使用時的外部事件以及使用差異

function Usage({
  onToggle = (...args) => console.log(`onToggle`, ...args),
// 額外的點選事件
  onButtonClick = () => console.log(`onButtonClick`),
}) {
  return (
    <Toggle onToggle={onToggle}>
      {({on, getTogglerProps}) => (
        <div>
// on屬性通過getTogglerProps 賦值
          <Switch {...getTogglerProps({on})} />
          <hr />
// 試想你會怎麼寫?你可能會寫一個行內函式 ?如果我們直接只寫自己的事件,那麼toggle的切換就無法完成;但寫成這樣toogle內就不方便修改或者外部使用時外部與元件內觸發的事件本就是不同的。
<button
          {...togglerProps}
            `aria-label`: `custom-button`,
            id="custom-button-id",
            onClick: {( => {
              onButtonClick()
              togglerProps.onClick()
            })},
        >
          {on ? `on` : `off`}
        </button>
// 將點選事件單獨作為屬性傳入,預設執行其預設的點選,同時將其屬性一次性封裝傳入
          <button
            {...getTogglerProps({
              `aria-label`: `custom-button`,
              onClick: onButtonClick,
              id: `custom-button-id`,
            })}
          >
            {on ? `on` : `off`}
          </button>
        </div>
      )}
    </Toggle>
  )
}
複製程式碼

小結

看上去有點亂,我簡單梳理下當我們的元件事件除了使用元件之外,希望方便的獲取元件屬性,或者需要針對一些元件事件增加額外的事件邏輯而進行一定的解耦,那麼可以通過額外定義一個getToggleProps的方法來簡化操作,也可以用來支援業務特殊的元件回撥函式方便解耦。

相關文章