I am new in react native. I've been dealing with this big project, that contains too many strings that can be reused many places in the project. So I created a strings.js file , as in android's strings.xml, to store all reusable strings in one file like this,
export const SOME_STRING = 'Some value';
export const ANOTHER_STRING = 'Another value';
...
and imports whenever i needed.
So these are my questions...
1) Is this a good approach ?
2) Is there any alternative to this ?
You don't need to export each value. One better way I know is to export
const SOME_STRING = 'Some value';
const ANOTHER_STRING = 'Another value';
module.exports = {
SOME_STRING:SOME_STRING,
ANOTHER_STRING:ANOTHER_STRING
}
Or you may like to wrap all of this in 1 constant object
const APPLICATION_CONSTANTS = {
SOME_STRING : 'Some string',
ANOTHER_STRING : 'Another string'
}
export default APPLICATION_CONSTANTS;
Usage
import APPLICATION_CONSTANTS from './strings';
APPLICATION_CONSTANTS.SOME_STRING
I am assuming you are using a lot of string because of styling. I do the same thing where I try to extract the maximum amount of styling information to a separate folder with different styling files. Not only variables, but commonly grouped styles as well.
For example:
const styleVariables = {
// Fonts
baseFontSize: 16,
largeFontSize: 24,
// Icons
smallIconSize: 24,
mediumIconSize: 36,
// Colors
mainColor: '#e85e45',
secondaryColor: '#a0c5d8',
offWhite: '#f4f4f4',
darkColor: '#404040',
// Dimensions
headerHeight: 70,
shadowSize: 6
};
export default styleVariables;
And I reference my variables in other styling files where related information is grouped:
/* presentation.js */
import variables from './variables';
export const shadow = {
shadowColor: variables.darkColor,
shadowRadius: variables.shadowSize,
shadowOpacity: 0.35,
shadowOffset: {width: 0, height: 0}
};
export const centered = {
alignItems: 'center'
justifyContent: 'center'
}
And in then in my components I just reference my styles:
import variables from './../styles/variables';
import {centered, shadow} from './../styles/presentation';
class RoundButton extends React.PureComponent {
render() {
return (
<View style={styles.button}>
{this.props.children}
</View>
);
}
}
const styles = StyleSheet.create({
button: {
width: variables.buttonSize,
height: variables.buttonSize,
borderRadius: variables.buttonSize / 2,
...centered
...shadow
}
For text styles and common presentations this really reduces code, and allows for easy modification in just one place.
Simple just you need to create one constantString.js file, and whenever you want to use string from the constantString.js file just import in particular file.
constantString.js
module.exports = {
SOME_STRING : 'Some string',
ANOTHER_STRING : 'Another string'
}
Use string from constantString.js something like,
import constStr from './constantString';
console.log(constStr.SOME_STRING); // Some string
console.log(constStr.ANOTHER_STRING); // Another string
You can use react-intl to play with strings, dates and numbers.
which will provide default functions to handle your data.
import { defineMessages } from 'react-intl';
const messages = defineMessages({
SOME_STRING : 'Some value',
ANOTHER_STRING : 'Another value',
});
export default messages;
learn more about react-intl library
Related
I'm trying to extend the chakra ui theme but i get this error.
error - Error: Objects are not valid as a React child (found: object with keys {semanticTokens, direction, breakpoints, zIndices, radii, blur, colors, letterSpacings, lineHeights, fontWeights, fonts, fontSizes, sizes, shadows, space, borders, transition, components, styles, config}). If you meant to render a collection of children, use an array instead.
Here is my code.
import { extendTheme } from '#chakra-ui/react'
import { mode } from '#chakra-ui/theme-tools'
const styles = {
global: props => ({
body: {
bg: mode('#f0e7db', '#202023')(props)
}
})
}
const components = {
Heading: {
variants: {
'section-title': {
textDecoration: 'underline',
fontSize: 20,
textUnderlineOffset: 6,
textDecorationColor: '#525252',
textDecorationThickness: 4,
marginTop: 3,
marginBottom: 4
}
}
},
Link: {
baseStyle: props => ({
color: mode('#3d7aed', '#ff63c3')(props),
textUnderlineOffset: 3
})
}
}
const fonts = {
heading: "'M PLUS Rounded 1c'"
}
const colors = {
grassTeal: '#88ccca'
}
const config = {
initialColorMode: 'dark',
useSystemColorMode: true
}
const theme = extendTheme({ config, styles, components, fonts, colors })
export default theme
I am using react-native-elements in my react-native application.
My app is wrapped with the ThemeProvider to pass the theme down to all components.
<SafeAreaProvider>
<ThemeProvider theme={Theme}>
<Loader visible={loader.loading} text={loader.message} absolute={true} />
<RootNavigation />
</ThemeProvider>
</SafeAreaProvider>
In the theme file i define the values i want to use across the app.
const theme = {
colors: {
primary: '#6A69E2',
primaryDark: '#4747c2',
primaryLight: 'rgba(106, 105, 226, 0.35)',
gray: {
dark: '#242424',
default: '#666',
medium: '#999',
light: '#ccc',
lightest: '#e7e7e7',
},
},
text: {
size: {
small: 12,
default: 16,
large: 18,
h1: 26,
h2: 22,
h3: 20,
},
},
Text: {
style: {
fontSize: 16,
color: '#242424',
fontFamily: 'Roboto',
},
},
Button: {
style: {
borderRadius: 50,
},
disabledStyle: {
backgroundColor: 'rgba(106, 105, 226, 0.35)',
},
},
};
export default theme;
For the values the original theme of react-native-elements providing this is working. For example i can access the colors by using
const theme = useTheme()
theme.colors.primary
But when i want to add some new properties like primaryDark i'll get an linter error.
Object literal may only specify known properties, and 'primaryDark' does not exist in type 'RecursivePartial<Colors>'.ts(2322)
In the doc of react-native-elements is a part about declaration merging, but i don't understand how i can archive this
https://reactnativeelements.com/docs/customization/#typescript-definitions-extending-the-default-theme.
Somebody could help me with this?
Well, declaration merging still works. This seems like a bug on the lib's part.
Their doc says you can augment the Color interface in module 'react-native-elements'. But currently (as of 2021-04-18, with v3.3.2) that interface is actually hidden inside module 'react-native-elements/dist/config/colors', not directly exposed at the top level, weird.
I suggest you file an issue to their repo. Never mind, someone already filed the issue.
Tested on my machine, following solution works.
import React from 'react'
import { useTheme, ThemeProvider } from 'react-native-elements'
declare module 'react-native-elements/dist/config/colors' {
export interface Colors {
primaryDark: string
primaryLight: string
}
}
const ChildComp = () => {
const theme = useTheme()
theme.theme.colors.primaryDark // <-- No more error 🎉
return <div>foobar</div>
}
Reply to OP's comment. You can augment interface however you like, as long as the augmented key doesn't exist before. For example add foobar key to FullTheme.
declare module 'react-native-elements' {
export interface FullTheme {
foobar: string
}
}
I am able to create QR Code with single value by using react-native-qrcode-svg package. But not able to add multiple values like name,email, etc.
I have tried these :
Packages:
npm install react-native-svg --save
react-native link react-native-svg
npm install react-native-qrcode-svg --save
Code for generating QR Code using single value.
import * as React from 'react';
import QRCode from 'react-native-qrcode-svg';
export default class App extends React.Component {
render() {
return (
<QRCode
value="Here I want to add name, email,etc"
/>
);
};
}
I want to generate something like this
You can use rn-qr-generator module to create QRCode Image with a given string.
To generate a QRCode image with an object just do something like this
import RNQRGenerator from 'rn-qr-generator';
RNQRGenerator.generate({
value: JSON.stringify({ email: 'some.email.com', name: 'Name' })
height: 100,
width: 100,
base64: false, // default 'false'
backgroundColor: 'black', // default 'white'
color: 'white', // default 'black'
})
.then(response => {
const { uri, width, height, base64 } = response;
this.setState({ imageUri: uri });
})
.catch(error => console.log('Cannot create QR code', error));
According to the documentation here, https://www.npmjs.com/package/react-native-qrcode-svg, the value can be an array:
String Value of the QR code. Can also accept an array of segments as defined in Manual mode. Ex. [{ data: 'ABCDEFG', mode: 'alphanumeric' }, { data: '0123456', mode: 'numeric' }, { data: [253,254,255], mode: 'byte' }]
Hence the code should be
import * as React from 'react';
import QRCode from 'react-native-qrcode-svg';
export default class App extends React.Component {
render() {
return (
<QRCode
value="[{ name: 'my name'},{ email: 'email#email.com' }]"
/>
);
};
}
I never used react, but shouldn't be something like
value={`"name={name},email={email},phone={phone}"`}
enough to compute the value?
<QRCode
value={`${email},${mdp}`}
/>
if you want to read the data:
data=result.split(",")
So, I want to setup multilanguage support for my app. On the base of react-native. However, when looking at i18n solution it pops up an error:
I followed the installation step on https://github.com/AlexanderZaytsev/react-native-i18n, everything installed and got linked ok, without errors. Tried to setup most basic sample on completely new project. The "App.js" file looks as follows:
import I18n from 'react-native-i18n'
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>{I18n.t('greeting')}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I18n.fallbacks = true
I18n.translations = {
en: {
greeting: 'Hi!'
},
fr: {
greeting: 'Bonjour!'
}
}
Whenever I try to run it on emulator, the systems pops that error. Driving me nuts at this point. Any known solutions I have missed at this point?
In your project, execute:
$ react-native link
and reboot.
See:
https://github.com/AlexanderZaytsev/react-native-i18n#manual-setup
https://facebook.github.io/react-native/docs/linking-libraries-ios.html#step-2
is it possible to separate var styles = StyleSheet.create from React.component into different script in react native?
that's possible. just create a js file with this pattern:
'use strict';
var React = require('react-native');
var myStyles = React.StyleSheet.create({
style1: { },
style2: { }
)}
module.exports = myStyles;
then in your component js use require to use that style sheet e.g. assuming your style js file is named phongyewtong.js
var s = require('../the/path/to/phongyewtong');
usage:
<View style = {s.style1} />
Both of the below links explain very well how to move styles out of your 'structural' code :
https://hackernoon.com/manage-react-native-project-folder-structure-and-simplify-the-code-c98da77ef792
https://medium.com/the-react-native-log/tips-for-styling-your-react-native-apps-3f61608655eb
Basically (copying code snippet from above link #2) have your styles in separate JS, say text.js file :
const text = StyleSheet.create({
p: {
color: 'black',
fontFamily: 'Open Sans',
fontSize: 14,
},
title: {
fontWeight: 'bold',
color: 'black',
fontFamily: 'Open Sans',
fontSize: 20,
}
});
export default text;
In React component, you can simply import this text style, and use it directly
<Text style={text.p}>settings</Text>
Hope this helps.
In a more recent React Version (0.31) I used this code:
import React, { Component, PropTypes } from 'react';
import { StyleSheet } from 'react-native';
var styles = StyleSheet.create({
...
});
module.exports = styles;