I was putting together a react-native app and noticed one glaring annoyance. Every time I wanted to use a theme when creating a stylesheet, I had to import the theme from an external file to use it.
Something like this
import { StyleSheet } from 'react-native'
import { theme } from 'path-to-theme/theme.js'
const styles = StyleSheet.create({
container: {
backgroundColor: theme.background
}
})
Coming from a React background, what I was wanting to do is get the theme provided to the constructor of sorts, so I don't have to do an import every time. Kind of like material-ui does it
import { StyleSheet } from 'custom-stylesheet-path/stylesheet.js'
const styles = StyleSheet.create(theme => {
container: {
backgroundColor: theme.background
}
})
But I'm not sure how to go about the implementation. Especially providing the theme to the stylesheet constructor. Anybody got any experience with this? Even just a starting point
NativeBase is able to implement themes in react native. The way that it does it, is to create the standard set of react native components and then require that you import those elements from native-base rather than react-native.
Example:
import { Label } from 'native-base'
Rather than:
import { Text } from 'react-native'
Related
I have SVG Icon library which exports all the SVG images as modules like below
Icon Library
import React from 'react';
import Clock from './icons/clock.svg';
import Calender from './icons/calender.svg';
export const ClockIcon = Clock
export const CalenderIcon = Calender;
And I am using the library in application like below
Using Icon library in application
import React from 'react';
import { Button as MUIButton } from '#mui/material';
import './button.scss';
import { Icon } from '../Icons/Icon';
import { ClockIcon } from '../../../dist';
function Button(props: any) {
const { label, ...rest } = props;
return <>
<Icon icon={ClockIcon} />
<MUIButton {...rest}>{label}</MUIButton>
</>;
}
export default Button;
When running webpack build inside the build both SVGs are present
Even though If I am using only Clock Icon Calender Icon also gets added to the bundle.
Is there any way to ensure only used assets are included in the bundle.
I don't want to directly import SVG Icons like below to achieve this
import ClockIcon from '../../../dist/icons/clock.svg';
In webpack there is a optimization parameter called usedExports which will ensure the unused exports are not getting included in the bundle. But the code only works for unused javascript code. Not for svg files.
So, I'm new to React Native, and I'm trying to build out a basic app, but every time I launch it on my android emulator, I get a syntax error telling me that 'none of these files exist" and it is referring to an image. Here is a screen capture of the emulator, as well as my vs code workspace.
Here is the code if anyone wants to copy it and mess with it.
WelcomeWindow.js:
import React from 'react';
import { ImageBackground } from 'react-native-web';
function WelcomeWindow(props) {
return (
<ImageBackground
style={styles.background}
source={require("../assets/background.jpg")}>
</ImageBackground>
);
}
const styles = StyleSheet.create({
background: {
flex: 1,
}
})
export default WelcomeWindow;
App.js:
import WelcomeWindow from './app/screen/WelcomeWindow';
export default function App() {
return (
<WelcomeWindow />
);
}
I'm certain the path is correct, I'm thinking this is more of a bug somewhere, and I don't really know how to fix it. I've tried looking for a solution, and I've come across a sources saying this is specifically an issue when using android studio, which I am using. Again, I'm not sure about that. If anyone can help me out, it would be greatly appreciated!
I figured out what was going on. For some reason, the automatic import for ImageBackground is from react-native-web.
import React from 'react';
import { ImageBackground } from 'react-native-web';
It should only be react-native.
import React from 'react';
import { ImageBackground } from 'react-native';
We have a few cases in our app where #emotion/styled is not rendering the styles for a component. The weird thing is, it is applying a somewhat class name to the component, yet the class has no associated styles, as seen in this image.
You would expect to see a green background for this particular div, but we don't see anything. This is also happening when we render SVG content directly in React and use the CSS fill property in emotion. The logo will sometimes appear all black as the fill is never included in the resulting generated emotion CSS, but other times it is. This later case usually occurs after a rebuild/redeploy of the app loading for the first time in the browser. After a refresh, it shows the correct fill. However, in the first case, it never worked.
In the first case, we initially had some react useEffect code make a BE API call to fetch some data, and we displayed that data in the component. In this case it worked fine, the emotion styles were applied correctly. However I refactored it to take a static value and render immediately (instead of the async BE API call), and now all of a sudden emotion styles are not being applied.
This only appears on staging environments which have a build, not locally which use the <style> tags to hold emotion content. We use the emotion babel plugin to build, but don't do server-side rendering.
This tells me there is something fishy going on with emotion and static/fast rendering at some point in the component tree. It seems that if we apply an async wait to the system, the styles appear, but otherwise they don't.
Any ideas what could be happening? Sorry I can't share any code but literally it is this vs. this:
// Static.tsx
import React from 'react'
import styled from '#emotion/styled'
const Text = styled.div`
background: green;
`
const StaticComponent = () => {
return <Text>static</Text>
}
export default StaticComponent
// Async.tsx
import React, { useEffect, useState } from 'react'
import styled from '#emotion/styled'
const Text = styled.div`
background: green;
`
const AsyncComponent = () => {
const [text, setText] = useState(null)
useEffect(() => {
setTimeout(() => {
setText('async')
}, 1000)
})
return text ? <Text>{text}</Text> : null
}
export default AsyncComponent
Then something like this to render:
import React from 'react'
import ReactDOM from 'react-dom'
import Async from './Async'
import Static from './Static'
ReactDOM.render(
<><Async/><Static/></>,
document.getElementById('root')
)
This is a general ES6 question, but I've encountered it in the context of React Native. The basic problem is that I want to override some components that I usually import from the 'react-native' module with my own components. My method for doing this looks like the following:
Instead of requiring components with import { Text, View, etc } from 'react-native'
require them like this: import { Text, View, etc } from './ui_components'
where ui_components.js looks something like:
export * from 'react-native'
The issue is, how do I add my own components to this export? Ideally I'd be able to add them in ui_components.js by doing something like this:
import * as RN from 'react-native'
RN.Text = myTextComponent
RN.View = myViewComponent
export * from RN
But this doesn't quite work. Any ideas?
You need to import React Native's component and reexport it, with or without extensions from your side - it's up to you.
But remember - don't ever override React's internals (or any other's internals). Components are composable, yay!
For example, here, I am creating my custom Text component cause I want all texts in my app to be red by default. Also I want it to be configurable if I need different color for title/subtitle/whatever...
import React from 'react';
import { Text as NativeText } from 'react-native';
export default function Text({ style, ...props}) {
return <NativeText style={[ { color: 'red' }, style]} {...props} />
}
Got an idea?
Good, now to folder structure...
ui_components
| - index.js
| - Text.js
// Text.js
// See example above...
// index.js
export { default as Text } from './Text';
// In your app
import { Text } from './ui_components';
I'm a bit perplexed on what should be a simple fix. I'm running a react-native project on version 0.27.2, and all of my ios.js files successfully import Stylesheet except one.
The import looks like this:
import React, {Component} from 'react';
import {
AppRegistry,
StyleSheet,
ScrollView,
Text,
View,
} from 'react-native';
import {
Cell,
CustomCell,
Section,
TableView
} from 'react-native-tableview-simple';
const styles = Stylesheet.create({
container: {
backgroundColor: 'rgb(20,25,30)',
}
}
);
The Stylesheet.create({}) function is what ultimately causes the error Can't find variable Stylesheet to be thrown. However, I've declared styles the same way in every other file with the same imports, and those rendered the styles with no error.
The only thing that's different in this file is that multiple classes have been declared. I'm new to React, so I don't know if this could cause an issue. Does anyone have any idea what could be causing this?
You mixed the case, you need to write
const styles = StyleSheet.create({
like you named it when you imported it.
I just run into same issue and found out that types are in different module. If you have correct case(StyleSheet) and still doesn't work, it's very likely that you do not have type module installed. Just execute this line in cmd -
npm install --save #types/react-native
It should do the trick.