はじめに
React(およびReact Native)で複数ボタンを縦に配置する際、ボタンごとにmarginTop(marginBottom)をあてるのは少々面倒です。
React.children.mapを利用して、childrenにボタンをいれたとき、ボタンの数に関わらずに間にマージンをいれてくれるようなラッパーをつくってみました。
実装
Children.mapをつかうことで、children内の各要素を制御することができます。
今回の場合、一番上(index = 0)のボタン以外に、cloneElementでmarginTopをスタイル(containerStyle)に加えています。
AutoSpacingWrapper.tsx
import React, {
Children,
ReactNode,
cloneElement,
isValidElement,
useMemo,
} from "react";
type Props = {
children?: ReactNode;
};
const AutoSpacingWrapper = ({ children }: Props) => {
const buttons = useMemo(() => {
return Children.map(children, (child, index) => {
if (index > 0 && isValidElement(child)) {
return cloneElement(child, {
containerStyle: { ...child.props.containerStyle, marginTop: 15 },
});
}
return child;
});
}, [children]);
return <>{buttons}</>;
};
作成したAutoSpacingWrapper
をつかう際は、childrenにボタンを加えていくだけでOKです。
<AutoSpacingWrapper>
<Button onPress={handlePressButton1}>ボタン1</Button>
<Button onPress={handlePressButton2}>ボタン2</Button>
<Button onPress={handlePressButton3}>ボタン3</Button>
</AutoSpacingWrapper>
参考資料