React Native View style props as inline props - javascript

This is not bug. Is just to be sure on the View styles props object is supporting as inline props also?
Example (Classic way, also written in React Native Doc)
function App() {
return (
<View style={styles.box}></View>
)
}
const styles = Stylesheet.create({
box: {
height: 200,
width: 200,
backgroundColor: 'tomato',
},
})
Nothing wrong on the example above, working expected. However, I was try to build style box component which inspired by React Material UI's Box component and I found out there is another simple way to do which is you can write the style property in View as props. following example I tried on React Native 0.62.
function App() {
return (
<View
height={200}
width={200}
backgroundColor="tomato"
></View>
)
}
This is not written in the React Native Docs, just want to be sure is it safe to use? 🧐

here is example
function App() {
return (
<View
style={{
height:200,
width:200,
backgroundColor:"tomato"}}
>
//here your code
</View>
)
}

here an other example style class with inline style
function App() {
return (
<View
style={[style.classNameHere,{
height:200,
width:200,
backgroundColor:"tomato"}]}
>
//here your code
</View>
)
}

Related

React Native Styled Components how to pass non specific styles as props for re usable components

Given the following simple component example which uses styled components for the Pressable:
const StyledPressable = styled.Pressable = props => props.buttonStyle
const Icon: FC<{buttonStyle: string}> = ({buttonStyle}) => {
return (
<StyledPressable buttonStyle={buttonStyle} >
<SomeIconComponent/>
</StyledPressable>
)
}
I would like to create a reusable component which takes in style props while still using styled components. Normally using the vanilla react native styles, this is really simple one would just pass in the style object as a prop an use it as a value in the necessary component. How would i achieve this behavior using styled components? my initial guess is that the buttonStyle has to be a string in the same format as styled components, but how would i make it so that the style which is declared inside the '' of lets say StyledPressable in this example is equal to the passed buttonStyle prop?
Since i am learning styled components, i am very open to any other way to achieve this behavior while using styled components.
import styled from "styled-components/native"
const Pressable = styled.Pressable(props => (props.buttonStyle))
export default function App() {
return (
<View style={styles.container}>
<Pressable buttonStyle={{ backgroundColor: "pink" }}>
<Text>This is button</Text>
</Pressable>
</View>
);
}
Inder's answer using some Typescript
import styled from "styled-components/native"
interface PressableProps {
buttonStyle?: CSSObject
}
const Pressable = styled.Pressable<PressableProps>({ buttonStyle }) => buttonStyle)
export default function App() {
return (
<View style={styles.container}>
<Pressable buttonStyle={{ backgroundColor: "pink" }}>
<Text>This is button</Text>
</Pressable>
</View>
);
}

Component function can't recognize this operator in react native

Basically, I want to call function (class method) from inside the functionComponent in react-native. Only way i can do it by passing as a props as shown in example B (image with debugging info). I want to try it like in example A (image with debugging info); Is there some way to achieve that (not using props)? Or there is whole another way to do it, any suggestion or tips or tricks would be nice. Or am i missing something.
Code for Example A.
//Example A
import React from 'react';
import { Text, View, Button } from 'react-native';
export default class RegisterScreen extends React.Component{
state = { message: "state message"};
openDialog(){
alert("hello..");
}
funcComponent({text}){
console.log(this);
console.log(this.state.message);
return(
<View>
<Text>{text}</Text>
<Button onPress={()=> this.openDialog()} title="Open"/>
</View>
);
}
render(){
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<this.funcComponent text="hello from component." />
</View>
);
}
}
Example A Debugging Report Image
Code for Example B
//Example B
import React from 'react';
import { Text, View, Button } from 'react-native';
export default class RegisterScreen extends React.Component{
state = { message: "state message"};
openDialog(){
alert("hello..");
}
funcComponent({text, openDialog, context}){
console.log(context);
console.log(context.state.message);
return(
<View>
<Text>{text}</Text>
<Button onPress={()=> openDialog()} title="Open"/>
</View>
);
}
render(){
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<this.funcComponent text="hello from component." openDialog={this.openDialog} context={this} />
</View>
);
}
}
Example B Debugging Report Image
Edit:
Ok, basically the problem is with the component, we can't just use "this" operator inside the functioncomponent coz we are using in the <this.funcComponent> (in Example A) that is why we need to pass this operator as props (which is done in Example B). In Example A "this" operator is out of the scope so that is why we need to pass as props.
Hope this is helpful to other who is facing this problem.
Edit 2: Solution for what i looking for
I found new solution for using "this" operator inside method or function, to use this operator we need to make arrow function, which makes the function inside the scope of the class.
(Basically it's a ES6 pitfall) reference: #doppio react native Flatlist navigation
Code for Example C
//Example C
import React from 'react';
import { Text, View, Button } from 'react-native';
export default class RegisterScreen extends React.Component{
state = { message: "i m state message"};
openDialog(){
alert("hello..");
}
funcComponent=({text}) => {
console.log(this);
console.log(this.state.message);
return(
<View>
<Text>{text}</Text>
<Button onPress={()=> this.openDialog()} title="Open"/>
</View>
);
}
render(){
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<this.funcComponent text="hello from component." />
</View>
);
}
}

Complete explanation about Context API in react native

I'm a little bit confused about how Context API works
as the docs said about Context Provider:
Accepts a value prop to be passed to consuming components that are descendants of this Provider. One Provider can be connected to many consumers. Providers can be nested to override values deeper within the tree.
I just start to try a simple code like this:
//App.js
export default class App extends React.Component {
constructor(props) {
super(props);
this.changeColor=(color, value)=>{
this.setState({[color]:value})
}
this.state={
changeColor:this.changeColor,
red:0,
green:0,
blue:0,
}
}
render() {
console.disableYellowBox = true;
return (
<ThemeContext.Provider value={this.state}>
<InitialScreen/>
</ThemeContext.Provider>
);
}
}
//InitialScreen.js
export default class Login extends Component {
render() {
return (
<ThemeContext.Consumer>
{({red, green, blue, changeColor})=>(
<View style={{flex:1}}>
<View style={{flexDirection:'row', justifyContent:'space-between'}}>
<Text>Red: </Text>
<Slider
style={{width:'80%'}}
minimumValue={0}
maximumValue={255}
step={1}
value={red}
onValueChange={(e)=>{changeColor('red', e)}}
/>
</View>
<View style={{flexDirection:'row', justifyContent:'space-between'}}>
<Text>Green: </Text>
<Slider
style={{width:'80%'}}
minimumValue={0}
maximumValue={255}
step={1}
value={green}
onValueChange={(e)=>{changeColor('green', e)}}
/>
</View>
<View style={{flexDirection:'row', justifyContent:'space-between'}}>
<Text>Blue: </Text>
<Slider
style={{width:'80%'}}
minimumValue={0}
maximumValue={255}
step={1}
value={blue}
onValueChange={(e)=>{changeColor('blue', e)}}
/>
</View>
<View style={[GlobalStyles.Center, {flex:1, backgroundColor:'rgb('+red+', '+green+', '+blue+')'}]}>
</View>
</View>
)}
</ThemeContext.Consumer>
);
}
}
//themeContext.js
import React from 'react';
export const themes = {
light: {
foreground: '#000000',
background: '#eeeeee',
},
dark: {
foreground: '#ffffff',
background: '#222222',
},
};
export const ThemeContext = React.createContext({
theme: themes.dark,
toggleTheme: () => {},
})
I don't know what's the meaning of Object inside React.createContext({...}), i can pass this.state in Provider value props that's mean I don't need to define anything in React.createContext({...}) AFAIK,
or maybe I'm doing something wrong so I'm out of Context function itself?
You're absolutely right, you don't need to provide anything in React.createContext in order to use it. The data you provided in createContext is merely default value and will be override as you set Context.Provider later on. However, I strongly recommend you to always provide a default value because of the following reasons:
By doing so you can think ahead of what kind of data your context would serve, hence help you to understand the structure of your code better. This habit would help you in long run
It gives whatever IDE you're using (Visual Studio for example) a clue of your Context data and it would give better hints as you code

React Native Swiper multiple images

I'm using the react-native-swiper, but I didn't find any solution for my problem in the docs. Currently it's show me one picture at once. But I want one and half, and always slide one by one. Is it possible somehow, because the slides have a strict width.
A design what I would achive:
There is my current code:
class Featured extends Component {
/**
* Render the featured box
*/
renderFeatured() {
return this.props.featured.data.items.map(object => (
<View style={styles.slide} key={object.id}>
<FeaturedBox
id={object.id}
image={Helpers.getPrimaryImage(object.images)}
text={object.name}
/>
</View>
)
);
}
render() {
if (Helpers.isObjectEmpty(this.props.featured)) {
return (
<View />
);
}
return (
<View>
<Swiper
style={styles.wrapper}
height={150}
horizontal={false}
showsPagination={false}
>
{this.renderFeatured()}
</Swiper>
</View>
);
}
}
const styles = StyleSheet.create({
wrapper: {
},
slide: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
});
Basically the FeaturedBox is just an image.
I found the solution, and change the Swiper to Carousel.
I had the same problem with you.
I tried many times, eventually solved this problem and I created npm package for these use cases.
First of all, You can solve this error by adding specific width in the images via your device.
If your use cases is adding multiple images, then you can solve that easily by using method below.
Hope react-native-image-swiper helps you.
usage
import {Dimensions} from 'react-native';
import ImagesSwiper from "react-native-image-swiper";
const { width, height } = Dimensions.get("window");
<ImagesSwiper width={width} height={height-400} />
I suggest you to use react-native-snap-carousel
follow below link for more details
https://www.npmjs.com/package/react-native-snap-carousel
You can do this via following code;
<Swiper removeClippedSubviews={false}>
<View style={{width: screenWidth - 100}}></View>
<View style={{marginLeft: - 100}}> </View>
</Swiper>

React Native: WebView height isn't being set properly

I'm having a problem with a WebView in my React Native app. When no height for the WebView is specified, it defaults to about half the screen height (iPhone 6S). However, when I set a height with the help of Dimensions, it displays fine, but only the original half is interactive – ie. can only scroll using the top half of the screen.
Here are the main parts of my current code:
import React, { Component } from 'react';
import {
...
Dimensions,
...
WebView,
} from 'react-native';
let ScreenHeight = Dimensions.get("window").height;
let ScreenWidth = Dimensions.get("window").width;
class App extends Component {
render() {
return (
<View style={styles.container}>
...
<WebView
source={{uri: 'http://foo.com'}}
style={{height: ScreenHeight, width: ScreenWidth}}
/>
...
</View>
);
}
}
...
const styles = StyleSheet.create({
container: {
backgroundColor: '#bbb',
flex: 1,
},
...
});
AppRegistry.registerComponent('myApp', () => App);
I look forward to any help that can be offered :)
It's possible that an invisible view from your render function is being drawn on the bottom half of the screen.
With out seeing the rest of the render method I couldn't tell, still worth checking.
Thanks for the answers, guys. I've fixed my issue now, and it seems to be such an easy fix. I basically wrapped the WebView in it's own View container. I'm not sure whether it wasn't working because it had sibling elements (ie. NavBar and TabBarIOS – which I left off my previous snippet – sorry!), but the WebView now works great.
Here is my new render function:
render() {
return (
<View style={styles.container}>
<NavBar>
<View>
<WebView
source={{uri: 'http://foo.com'}}
style={{height: ScreenHeight, width: ScreenWidth}}
/>
</View>
<TabBarIOS>
...
</TabBarIOS>
</View>
);
}
Try adding flex style to WebView. Your code will look like this:
<View style={styles.container}>
...
<WebView
source={{uri: 'http://foo.com'}}
style={{flex:1}}
/>
...
</View>

Categories

Resources