React Native
This is a guide for setting up React Cosmos in a React Native project, with or without Expo.
Getting Started
Install the required packages:
npm i -D react-cosmos react-cosmos-native
Add cosmos
script to package.json:
"scripts": {
"cosmos": "cosmos-native"
}
Create a basic fixture at Hello.fixture.js
:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default () => (
<View style={styles.container}>
<Text style={styles.text}>Hello World!</Text>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 24,
},
});
Start React Cosmos:
npm run cosmos
You'll notice Cosmos generated a cosmos.imports.js
module, which becomes
relevant next. You can add this file to .gitignore.
🚀 Open localhost:5000 (opens in a new tab) in your browser.
The Hello
fixture will show up in your React Cosmos UI.
Nice, almost done 👍
At this point Cosmos should successfully read your fixtures. One more step before you can render them.
Set Up React Native Renderer
This is very similar to a custom bundler setup. Cosmos cannot plug itself automatically into React Native's build pipeline (Metro), but you can do it with minimal effort.
Here's a basic file structure to get going. You can tweak this after everything's working.
- App.cosmos.js
- App.main.js
- App.js
- Your production app entry point:
App.main.js
. - Your Cosmos renderer entry point:
App.cosmos.js
. - The root entry point that decides which to load:
App.js
.
If you're using TypeScript replace .js
file extensions with .tsx
.
First, rename your existing App.js
to App.main.js
.
Then add the Cosmos renderer under App.cosmos.js
:
import React, { Component } from 'react';
import { NativeFixtureLoader } from 'react-cosmos-native';
import { rendererConfig, moduleWrappers } from './cosmos.imports';
export default class CosmosApp extends Component {
render() {
return (
<NativeFixtureLoader
rendererConfig={rendererConfig}
moduleWrappers={moduleWrappers}
/>
);
}
}
Finally, create a new App.js
that routes between your main and Cosmos entry points based on enviromnent:
module.exports = global.__DEV__
? require('./App.cosmos')
: require('./App.main');
That's it!
Open your app in the simulator and the Cosmos renderer should say "No fixture selected". Go back to your React Cosmos UI, click on the Hello
fixture and it will render in the simulator.
Congratulations 😎
You've taken the first step towards designing reusable components. You're ready to prototype, test and interate on components in isolation.
App Fixture
You'll often want to load the entire app in development. The simplest way to do this without disconnecting the Cosmos entry point is to create an App fixture:
import App from './App.main';
export default () => <App />;
Initial Fixture
You can configure the Cosmos Native renderer to auto load a fixture on init.
<NativeFixtureLoader
rendererConfig={rendererConfig}
moduleWrappers={moduleWrappers}
initialFixtureId={{ path: 'src/__fixtures__/HelloWorld.ts' }}
/>
initialFixtureId
expects a fixture path relative to the project root. You'll find the exact path in cosmos.imports.js
as a key in the fixtures
object.
Troubleshooting
- React Native blacklists
__fixtures__
dirs by default (at least it used to). Unless you configure Cosmos to use a different directory pattern, you need to overridegetBlacklistRE
in the React Native CLI config (opens in a new tab).
React Native for Web
You can get Cosmos to mirror your fixtures on both DOM and Native renderers (opens in a new tab) using the following steps:
- Set up Cosmos for Native using the steps above.
- Set up
react-cosmos-plugin-webpack
as described here. - Start Cosmos with the
cosmos --expose-imports
command.