React(17) - Render props


Posted by TempuraEngineer on 2023-06-14

目錄


render props 是什麼

render props 是一種用於 React component 的設計模式,它可以將負責邏輯的組件、負責畫面的組件間解耦

雖然 render props 很好用,但是濫用的話會使得組件變得非常巢狀,所以務必慎用


render props 怎麼用

假設有一個列表組件,它的最左側固定是 index,最右邊的格子內可能是 2 個 checkbox,可能是一個表示狀態的 icon,也可能是文字等等狀況

那麼最右邊的格子的邏輯就不是固定的,所以我們可以把邏輯列表組件抽出去

MUI的Select也是透過 render props 的方式實現 UI 的字和 select 的 value 不同的


render props 怎麼寫

假設有一個 select

在某些頁面顯示 apple,value 也是 apple,另一個地方則是顯示 🍎,value 為 apple

那麼就需要一個 props 來在後面那個情況傳入回傳 ReactNode 的 function,來處理特殊的渲染邏輯

interface RenderPropsSelectProps<T> {
  options: { text: string, value: T }[];
  // 開一個props用來傳入不同的選染邏輯
  renderValue?: (select: T) => ReactNode;
}

const RenderPropsSelect = ({ options, renderValue }: RenderPropsSelectProps<string>) => {
  const [isMenuShow, setIsMenuShow] = useState(false);
  const [currentValue, setCurrentValue] = useState('');

  return (
    <div className="w-inherit">
      <div
        className="pointer border-2 flex justify-between items-center p-3"
        onClick={() => {
          setIsMenuShow(!isMenuShow);
        }}
      >
        {/* select顯示的字樣可能邏輯不同 */}
        {/* 在可能渲染邏輯會不一樣的地方使用render props傳入的function */}
        <div>{renderValue?.(currentValue) || currentValue}</div>

        <ArrowDropDownIcon />
      </div>

      {isMenuShow && (
        <ul className="list-style-none border-1">
          {options.map(({ value, text }) => (
            <li
              className="p-2 pointer"
              onClick={() => {
                setCurrentValue(value);
                setIsMenuShow(false);
              }}
            >
              {text}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};

用起來會像這樣

      <RenderPropsSelect
        options={fruitOptions}
        renderValue={(selected) => {
          if (isFruit(selected)) {
            return <p>{fruitMap[selected]}</p>;
          }
        }}
      />

      <RenderPropsSelect options={fruitOptions} />


參考資料

React pattern - Render Props!
Render props and render functions in React.
React docs beta - Passing data with a render prop
React - render props


#React #render props







Related Posts

[C#] 檢查 Sql Injection 非法字元

[C#] 檢查 Sql Injection 非法字元

Caffe & GoogLeNet,怎麼幫助機器人更好地辨識物體

Caffe & GoogLeNet,怎麼幫助機器人更好地辨識物體

[FE101] CSS part 1

[FE101] CSS part 1


Comments