目錄
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