Description
openedon Jun 5, 2024
Describe the bug
Implementing props.children, or any situation where you pass a react component from a parent to a child results in an infinite load in the browser and also the native application
To Reproduce
- use the below code snippet in a boilerplate such as:
https://github.com/dannyhw/expo-template-storybook
Code snippets
main.ts
import { StorybookConfig } from '@storybook/react-native';
const main: StorybookConfig = {
stories: ['./stories/**/*.stories.?(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-ondevice-controls',
'@storybook/addon-ondevice-actions',
],
};
export default main;
/stories/button.tsx
import React from 'react';
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
interface MyButtonProps {
onPress: () => void;
text?: string; //using text works like in the examples
children: JSX.Element; //this freezes the browser.
}
export const Button = ({ onPress, text, children }: MyButtonProps) => {
return (
<TouchableOpacity style={styles.container} onPress={onPress}>
<Text style={styles.text}>{children}</Text>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
container: {
paddingHorizontal: 32,
paddingVertical: 8,
backgroundColor: 'purple',
alignSelf: 'flex-start',
borderRadius: 8,
},
text: { color: 'white', fontSize: 16, fontWeight: 'bold' },
});
/stories/button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Text, View } from 'react-native';
import { Button } from './button';
const meta = {
title: 'Button',
component: Button,
args: {},
decorators: [
(Story) => (
<View style={{ padding: 16 }}>
<Story />
</View>
),
],
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Basic: Story = {
args: {
children: <Text>Button</Text>,
},
};
Expected behavior
Using children
in args and passing a JSX.Element (such as <Text />
) should not freeze the browser in web export and nor on a device. It work the same as passing a string into the button in the above example
Screenshots
These screenshots are in the browser, but the same behavior is also exhibited on a device; the splash screen stays up and the app never finishes loading after bundle download hits 100%
Using text:
eg:
export const Basic: Story = {
args: {
text: 'yo',
},
};
interface MyButtonProps {
onPress: () => void;
text?: string;
children?: JSX.Element;
}
export const Button = ({ onPress, text, children }: MyButtonProps) => {
return (
<TouchableOpacity style={styles.container} onPress={onPress}>
<Text style={styles.text}>{text}</Text>
</TouchableOpacity>
);
};
Using props.children (like the above code snippet)
on start | minutes later |
---|---|
this never loads
System:
Storybook Environment Info:
(node:206879) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
System:
OS: Linux 5.15 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish)
CPU: (32) x64 13th Gen Intel(R) Core(TM) i9-13900K
Shell: 5.8.1 - /usr/bin/zsh
Binaries:
Node: 21.6.2 - ~/.nvm/versions/node/v21.6.2/bin/node
npm: 10.2.4 - ~/.nvm/versions/node/v21.6.2/bin/npm <----- active
pnpm: 8.15.1 - ~/.local/share/pnpm/pnpm
npmPackages:
@storybook/addon-ondevice-actions: ^7.6.19 => 7.6.19
@storybook/addon-ondevice-controls: ^7.6.19 => 7.6.19
@storybook/react: ^7.6.19 => 7.6.19
@storybook/react-native: ^7.6.19 => 7.6.19
Additional Context
- using a managed workflow with "expo": "51.0.9"