How to create a custom Text - react native - javascript

I completed my project now I want to set my custom font to all Text component.
I think the best way is to create a custom Text component and replace it with default Text of react-native.
now how can I creating a custom Text component with default style?

To achieve that, you need to have a react native component that is configurable via style or other properties once instantiated.
For example you can have your custom react native component CustomText like this:
1. Function component
If you prefer the new way and you'll use it with hooks, use this part:
// CustomText.js
import React from 'react';
import {
Text,
StyleSheet,
} from 'react-native';
export default function CustomText(props) {
return (
<Text style={[styles.defaultStyle, props.style]}>
{props.children}
</Text>
);
}
const styles = StyleSheet.create({
// ... add your default style here
defaultStyle: {
},
});
2. Class component
If you prefer the old way with classes use this part:
// CustomText.js
import React from 'react';
import {
Text,
StyleSheet,
} from 'react-native';
export default class CustomText extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Text style={[styles.defaultStyle, this.props.style]}>
{this.props.children}
</Text>
);
}
}
const styles = StyleSheet.create({
// ... add your default style here
defaultStyle: {
},
});
And then on your main component you import and call that custom component, something like this:
import CustomText from './CustomText';
//... other imports go here.
// in the render method you call your CustomText component.
render(){
//...
<CustomText style={{ fontWeight: 60, }}>
This is custom Text
</CustomText>
}
Note: If you want only to change the style I think #Yanush solution is the best for that case.
I hope this is helpful.

I would suggest using a style instead of a custom component but it's up to you.
In my project I have created a file named "commonStyles.js" that looks like this:
export default StyleSheet.create({
textTitle: {
fontSize: 20,
color: '#dddddd',
fontFamily: 'YourCustomFont',
},
});
then I'm importing this file wherever needed using:
import stylesCommon from './styles/stylesCommon';
and each text that needs to be changed should look like this:
<Text style={stylesCommon.textTitle}>
This is my title
</Text>

this guide will help you on how to apply custom fonts, I have been using the method in my apps.
To create a custom text component
export default Text = (props)=>{
return(
<Text style={[styles.defaultStyles,props.style]}>{props.children}</Text>
)
}
Now in all the files where you have used Text from react native remove import from react native and add
import Text from './path/to/component'

Related

How do I create a reusable component in react native? with this example

I managed to render the component for myself after so long trying, sorry I am new to react native, but I want to use the <DarkLight> component to cover everything inside and style the whole application and be able to continue using everything, as an example : when we use a <view>: we put in the middle another functional component like <Text> or another <View> you can use everything inside it and in turn its properties, I want to use <DarkLight> in the same way as if it were a <View > that encompasses the entire app Modifying the styles or properties and placing more components inside it, such as placing a <table> inside <DarkLight> (the table is also a component created to reuse) to be able to give it properties or styles also separately or if I create another component like the example of the <Table> put it inside <DarkLight> and keep it working .... in <DarkLight> I put a <Text> and it does nothing, this is what I mean ..., and I keep using all with props, I took this example from expo co lor-schemes, I would like to make it a reusable component that encompasses my entire application so that I am able to reuse it in another application. I want to learn how to build reusable components. I see props and components I do not want to advance without understanding well, being able to create a component that I can reuse. But I'm not sure if in these cases I should use state .. someone can help me and explain and I apologize for the inconvenience. :>
// App.js
import React from 'react';
import Home from './src/Home'
export default function App() {
return (
<Home/>
);
}
// Home.js
import React from 'react';
import { Text, StyleSheet, View, useColorScheme, Button } from 'react-native';
import DarkLight from '../src/Components/Dark_Light.js'
export default function Home() {
return (
<DarkLight>
<Text>Hello World</Text>
</DarkLight>
);
}
// Dark_Light.js
import React from 'react';
import { Text, StyleSheet, View, useColorScheme } from 'react-native';
import {globalStyles} from '../Styles/globalStyles'
const ThemeDark = (props) => {
const colorScheme = useColorScheme();
const themeTextStyle = colorScheme === 'light' ? globalStyles.lightThemeText : globalStyles.darkThemeText;
const themeContainerStyle = colorScheme === 'light' ? globalStyles.lightContainer : globalStyles.darkContainer;
const {children} = props;
return(
<View style={[globalStyles.container, themeContainerStyle]}>
<Text style={[globalStyles.text, themeTextStyle]}>
Color scheme: {colorScheme}
{children}
</Text>
{children}
</View>
)
}
export default function DarkLight() {
return (
<ThemeDark>
</ThemeDark>
);
}
// globalStyles.js // the global styles would like to be able to pass properties to it and modify it, what am I doing wrong? and what should i do?
import { StyleSheet } from "react-native";
export const globalStyles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
lightContainer: {
backgroundColor: '#d0d0c0',
},
darkContainer: {
backgroundColor: '#242c40',
},
lightThemeText: {
color: '#242c40',
},
darkThemeText: {
color: '#d0d0c0',
},
});

Invariant Violation: Element type is invalid: expected a string. (Image error)

im trying to create a component in react native.
The example of the component is:
import React from 'react'
import PropTypes from 'prop-types'
import { View, Text, Image } from 'react-native'
const MyComponent = ({Text, Image}) => {
return (
<Text>{Text}</Text>
<Image source={require('../../assets/images/HeaderLogo.png')} />
)
}
MyComponent.propTypes = {
Text: PropTypes.string,
Image: PropTypes.string,
}
export default MyComponent
If i remove the component, everything works nice and well, but when i try with the image component, it returns the error on the following image:
(It works with a icon, but not with a image.)
the component is imported as follow:
import MyComponent from './MyComponent'
If i change the import to:
import { MyComponent } from './MyComponent'
i get another error (As following):
You are passing Text and Image as arguments (props) to your function.
Not sure where you are using the image prop; if you aren't you should remove it.
As for the Text argument, you need to change this to text with lowercase t. Anything you pass as prop is essentially an argument to a function. Using an Uppercase T conflicts with the JSX Text element, which is used in your render function and is typed < Text > in order to render the relevant UI element.
in short, remove all capitalised references to the text and image arguments you pass in. Your code should look like this:
import React from 'react'
import PropTypes from 'prop-types'
import { View, Text, Image } from 'react-native'
const MyComponent = ({text}) => {
return (
<Text>{text}</Text>
<Image source={require('../../assets/images/HeaderLogo.png')} />
)
}
MyComponent.propTypes = {
text: PropTypes.string,
}
export default MyComponent
Try importing and using Image like this
import myIMage from '../../sourcefile.png'
const Component = (props) => {
return (
<View>
<View />
<Image source={myImage} style={{height: 100, width: 100}} /> //style is important here
</View>
export default Component;
You don't need to pass Text and Image as props, because you import them. Uppercased names are used for components.
Also React expects one top level element to render, and you're passing two. To make this work you'll need to wrap them in View:
const MyComponent = ({text}) => {
return (
<View>
<Text>{text}</Text>
<Image source={{uri: require('../../assets/images/HeaderLogo.png')}} />
</View>
)
}

How can I create new global css classes on the fly in React?

I’m using Draft.js for a project. I created a component that allows you to choose a font from a menu, then apply that font to the selected text in the Draft.js editor.
The way I need to do this:
Dynamically add a #font-face rule for the selected font that includes the font name and file location;
Create a new CSS class containing the font-family property that uses the font name from the #font-face rule that was added; and
Apply that new CSS class to the selection.
I’ve gotten everything but #2 figured out. For #2, I’m not finding any clear methods or tools to use that allow me to create new CSS classes in the global space. I’m reading a lot about css-in-js, but everything seems bloated or overly complex.
I’m formatting the #font-face rule and class like this:
const newClass = {
'#font-face': [
{
fontFamily: `${font.label} ${FONT_FAMILY_PREFIX}-A`,
src: `url(/fonts/${font.value}-TD-Space.woff)`,
fontWeight: 'normal',
fontStyle: 'normal',
}, {
fontFamily: `${font.label} ${FONT_FAMILY_PREFIX}-B`,
src: `url(/fonts/${font.value}-TD.woff)`,
fontWeight: 'normal',
fontStyle: 'normal',
},
],
[`.${font.value}`]: {
fontFamily: `${font.label} ${FONT_FAMILY_PREFIX}-A, ${font.label} ${FONT_FAMILY_PREFIX}-B`,
},
})
But I’m just not sure where to put it so it’s accessible across the app.
Does this require the help of some package or is there a simpler way I can manage it without?
The simplest way is probably to use React's Context feature (docs here)
Basically, you define a context like this:
// style-context.js
export const Styles = {
style1: {
fontFamily: '"Times New Roman", Times, serif',
fontSize: '12px'
},
style2: {
fontFamily: 'Arial, Helvetica, sans-serif',
fontSize: '16px'
},
};
export const StyleContext = React.createContext({
theme: styles.style1, // default value
changeTheme: (newTheme) => {}
}
);
Then, you wrap your App like this:
// App.js
import React, { Component } from 'react'
import { FontContext, styles } from './style-context'
class App extends Component {
constructor(props) {
super(props)
// Function to change the theme
this.chooseTheme = (newTheme) => {
this.setState({
theme: styles[newTheme]
})
}
// State includes the current theme and function to change it
this.state = {
theme: styles.style1,
chooseTheme: this.chooseTheme
}
}
render() {
return (
// Wrap with the context's Provider, and pass in the theme from
// the state. Those state values will be available from all
// children, no matter how deep.
<StyleContext.Provider value={this.state}>
<div className="App">
{/* components */}
</div>
</StyleContext.Provider>
);
}
}
There are two ways to use the context, then. First, you can reference it in any child component like this:
// SomeComponent.js
import React, { Component } from 'react'
import {StyleContext} from './style-context'
class SomeComponent extends Component {
render() {
return (
<div style={
this.context.theme
}>
{/* ... */}
</div>
)
}
}
SomeComponent.contextType = StyleContext
export default SomeComponent
Really simple. The other way to access it is like this, which is useful if you have multiple Contexts you're combining on a single Component:
// TestButton.js
import React, {Component} from 'react'
import {StyleContext} from './style-context'
class TestButton extends Component {
render() {
return (
<StyleContext.Consumer>
{
// The contents of the Consumer tag will receive the
// 'value' prop set at the Provider level, which is,
// in this case, the App state containing the current
// theme and function to change it
({theme, chooseTheme}) => (
<button onClick={() => {chooseTheme('style2')}} style={theme}>Change Font</button>
)
}
</StyleContext.Consumer>
)
}
}
export default TestButton
Doing that will mean you don't need to programmatically change the classes that different divs are given, nor need to generate CSS classes in the first place.
Also, one of my favorite tricks for assigning styles is to use Object.assign() to do so, like this:
...
<div style={Object.assign(
{ backgroundColor: 'red', fontSize: '16px' },
this.context.theme
)}>
...
That way, you can set default values, decoupling the Context from the Component, and allows the theme's style attributes to only override matching keys, combining the rest.

I want to render dynamic content from back-end that has html tags in react native

I have created an app that uses woo-commerce as back-end, the problem is many of the attributes of products that I receive from back-end are in html, when I tried to render it in it treated everything as text and as a result the whole string got printed to the screen with all the html tags which is not the desired result .
Is there any trick except for the Web-View to solve this problem?
For me the best way to render HTML code is to use a library called react-native-htmlview.
This is a simple example:
import React, {Component} from 'react';
import {
View,
StyleSheet,
} from 'react-native';
import HTMLView from 'react-native-htmlview';
class App extends Component {
state = {
html: '<p>Some Dummy <b>HTML</b> code</p>'
}
render() {
return (
<View style={styles.container}>
<HTMLView
value={this.state.html}
stylesheet={htmlStyleSheet}
/>
</View>
);
}
}
const htmlStyleSheet = StyleSheet.create({
p: {
color: 'red'
},
b: {
color: 'black'
}
})
const styles = StyleSheet.create({
container: {
paddingTop: 20,
}
})
export default App;
For more information:
https://github.com/archriss/react-native-render-html
Another option is to use WebView with source prop:
https://facebook.github.io/react-native/docs/webview
import React, { Component } from 'react';
import { WebView } from 'react-native';
class MyInlineWeb extends Component {
render() {
return (
<WebView
originWhitelist={['*']}
source={{ html: '<h1>Hello world</h1>' }}
/>
);
}
}

Setting container width on material-ui for React.js

I have recently started with React.js along with material-ui library. I am aware of the Grid system for layouts that material-ui uses. However, unlike Bootstrap, the container extends from end to end. Say, I want to create a global container to hold content which should have a max width of 1140px, what is the correct way to do it? Currently I am using withStyles provided by material-ui as shown by the code sample below
import React, { Component } from 'react';
import { withStyles } from '#material-ui/core/styles';
const styles = {
contentBody: {
maxWidth: '1140px',
marginLeft: 'auto',
marginRight: 'auto'
}
};
class ContentBody extends Component {
render() {
return (
<Grid container className={this.props.classes.contentBody}>
{this.props.children}
</Grid>
);
}
}
export default withStyles(styles)(ContentBody);

Categories

Resources