My FontPicker
is rendering a list of FontItem
components.
Each FontItem
should receive a boolean prop selected
.
Since my selectedFont
, controlled in the FontPicker
, is an animated value, is there any correct way to pass the selected
prop to my child without doing the selected
comparison inside each child component?
const {
selectedFont,
onPressItem,
onScroll,
onMomentumScrollEnd,
} = useFontPicker(scrollRef, { fonts, activeFont, itemWidth, onPick });
const renderFonts = () =>
fonts.map((font, index) => {
const fontProps = {
key: font,
fontFamily: font,
selectedFont, // <---- How to avoid passing the selected font? I mean, how can we pass just a boolean prop accessing the most up-to-date selectedFont.value??
style: [fontItemStyles.container, fontItemStyle],
textStyle: fontItemTextStyle,
onPress: onPressItem(index),
};
return <FontItem {...fontProps} />;
});
function FontItem({
fontFamily,
selectedFont, // <--- what about receiving a selected boolean prop instead?
style = styles.container,
textStyle,
onPress,
}) {
const { colors } = useTheme();
const selected = useDerivedValue(() => selectedFont.value === fontFamily); // <--- How do we calculate this on the parent's .map??
const animatedStyle = useAnimatedStyle(() => {
const backgroundColor = selected.value ? colors.onSurface : colors.backdrop;
return { backgroundColor };
});
const animatedTextStyle = useAnimatedStyle(() => {
const color = selected.value ? colors.primary : colors.onSurface;
return { color };
});
const handleOnPress = () => {
onPress?.(fontFamily);
};
const renderSample = () => (
<Animated.Text style={[{ fontFamily }, animatedTextStyle, textStyle]}>
Aa
</Animated.Text>
);
return (
<TouchableOpacity onPress={handleOnPress}>
<Animated.View
style={[
animatedStyle,
globalStyles.centeredContainer,
style,
]}
>
{renderSample()}
</Animated.View>
</TouchableOpacity>
);
}