logo-Chiyu

Chiyu

Blog

Here I share my stories.

React 怎麼把 props 傳給 children?

是要傳給 props.children 唷!不是單純 Parent 傳給 Child。

🕒 published on ー 2022. 1. 3.

thumbnail.png

Photo by Gaelle Marcel on Unsplash

Free Talk

為什麼會有這問題?

  1. 想把幾個 props 傳給全部的 { children } 用,因為小孩們要配合父母做一些事情,但 { children } 時而動態生成、時而手工 Hard Code 寫死。
  2. 不想每次用到作為 { children } 的 Child Component 時,就要重複手工傳 props,我就懶。
  3. 直覺 React 一定有內建模組可幫我做到這件事。

我在任一間公司從來都沒遇過要處理這問題的場合, 反倒是在家自己亂玩亂寫 Code 才突發其想到並解決了這件事, 覺得很適合寫篇筆記。

先確定,要真親子才可以

為什麼要真親子才可以?

就是如此呀,今天我就是設計好了要傳東西給 props.children,非 props.children 者當然會接不到我傳的東西,也就是說我要傳的東西只能透過 props.children 存取。

一旦確定 Component 們是真親子,就可以安心實作啦。我是 import 了 React 的 ChildrencloneElement 來做這件事。

編了一個配合 styled-components 使用的簡單範例,個人是想成把 { children } 抓來做成複製人 + 基因改造再來做正事這樣:

import React, { Children, cloneElement } from 'react';
import styled from 'styled-components';

// Parent Component 要用的
const Container = styled.div`
  width: ${({ width }) => `${width}px`};
  border-color: ${({ borderColor }) => borderColor};
`;
// Parent Component 登場
export const Parent = ({ children, border, width }) => {
  // 這行意思就是把 props 傳給 children,我只要傳 width 這個 prop 就好
  const childrenWithProps = Children.map(children, (child) => cloneElement(child, { width }));
  return (
    <Container border={border} width={width}>
      {childrenWithProps}
    </Container>
  );
};
// Child Component 要用的
const Card = styled.div`
  width: ${({ cardWidth }) => cardWidth};
  background-color: ${({ bgColor }) => bgColor};
`;
// 作為 `{ children }` 用的 Child Component 登場:
export const Child = ({ bgColor, size, ...props }) => {
  // ...props 裡就有從 <Parent /> 那傳來的 { width },把它解構賦值方便使用
  const { width } = props;
  // 總之就是要小孩自動自發的做出變化
  const getBasis = () => (size === 'small' ? 6 : 3);
  return (
    <Card bgColor={bgColor} cardWidth={`calc(${width / getBasis()}px)`}>
      <p>我是乖小孩</p>
    </Card>
  );
};

使用例:

<Parent border='1px solid black' width={1200}>
  <Child bgColor='red' size='small'>
  <Child bgColor='blue'>
</Parent>

Ending

我知道還有其他不少方法可以解決這個問題,不過我用這個方法解決了自己想到的問題,後續自己使用上也沒什麼不滿的,覺得暫且足矣,現在就先這樣了~!

Copyright © 2022 Chiyu