Why is my style not applied to my child component? - react-native

Good evening,
I have been trying to create custom card Component in react native that i can use everywhere i need it.
I apply a part of the style inside the component itself, and for the width, layout etc, where i need it. Then i am trying to use the spread operator to "merge" all the properties in the style of the child component. I saw it in a video tutorial, but it's not working for me, and i don't see what is wrong in my code :
import React from 'react';
import { View, Text, StyleSheet, TextInput, Button } from 'react-native';
import Card from '../components/Card';
import Color from '../constants/colors'
import Input from '../components/Input'
const StartGameScreen = props => {
return (
<View style={styles.screen}>
<Text style={styles.title}>Start a New Game!</Text>
<Card style={styles.inputContainer}>
<Text>Select a Number</Text>
<Input />
<View style={styles.buttonContainer}>
<Button title="Reset" color={Color.accent} onPress={() => {}} />
<Button title="Confirm" color={Color.primary} onPress={() => {}} />
</View>
</Card>
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
padding: 10,
alignItems: 'center'
},
title: {
fontSize: 20,
marginVertical: 10
},
inputContainer: {
width: 300,
maxWidth: '80%',
alignItems: 'center',
},
buttonContainer: {
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
paddingHorizontal: 15
},
input: {
width: 50
}
});
export default StartGameScreen;
And the child component :
import React from 'react';
import { View, StyleSheet } from 'react-native';
const Card = props => {
return (
<View style={{ ...styles.card, ...props.style }}> {props.children}</View>
);
};
const styles = StyleSheet.create({
card: {
shadowColor: 'black',
shadowOffset: { width: 0, height: 2 },
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 8,
backgroundColor: 'white',
padding: 20,
borderRadius: 10
}
});
export default Card;
Note : I tried with input and card, it's working for none of them.
Is that something that we were able to do but we can't anymore ?
Thank you
Have a nice weekend

Try this:
const Card = props => {
return (
<View style={[styles.card, props.style ]}> {props.children}</View>
);
};

Related

Text strings must be rendered within a <Text> component. When creating a button

I'm new to react native and trying to create a button, here is my StartScreen:
import React from 'react' import Background from '../components/Background' import AppButton from '../components/AppButton'
export default function StartScreen({ navigation }) {
return(
<Background>
<AppButton title="HEEEY!" size="sm" backgroundColor="#007bff" />;
</Background>
) }
Here is my AppButton:
import React from 'react'
import { StyleSheet, TouchableOpacity, Text } from "react-native";
export default function AppButton ({ onPress, title, size, backgroundColor }) {
return (
<TouchableOpacity
onPress={onPress}
style={[
styles.appButtonContainer,
size === "sm" && {
paddingHorizontal: 8,
paddingVertical: 6,
elevation: 6
},
backgroundColor && { backgroundColor }
]}
>
<Text style={[styles.appButtonText, size === "sm" && { fontSize: 14 }]}>
{title}
</Text>
</TouchableOpacity>
)
};
const styles = StyleSheet.create({
screenContainer: {
flex: 1,
justifyContent: "center",
padding: 16
},
appButtonContainer: {
elevation: 8,
backgroundColor: "#009688",
borderRadius: 10,
paddingVertical: 10,
paddingHorizontal: 12
},
appButtonText: {
fontSize: 18,
color: "#fff",
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase"
}
});
Here is my Background:
import React from 'react'
import { ImageBackground, StyleSheet, KeyboardAvoidingView } from 'react-native'
import { theme } from '../core/theme'
export default function Background({ children }) {
return (
<ImageBackground style={styles.background}>
<KeyboardAvoidingView style={styles.container} behavior="padding">
{children}
</KeyboardAvoidingView>
</ImageBackground>
)
}
const styles = StyleSheet.create({
background: {
flex: 1,
width: '100%',
backgroundColor: theme.colors.surface,
},
container: {
flex: 1,
padding: 20,
width: '100%',
maxWidth: 340,
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
},
})
When I try to run the application in my Android phone I get the following error:
Error: Text strings must be rendered within a component.
Blockquote
But I cant figure out where this error happens. Can someone spot the mistake?
You have an unnecessary semicolon (;) in your StartScreen JSX, remove it.
export default function StartScreen({ navigation }) {
return(
<Background>
<AppButton title="HEEEY!" size="sm" backgroundColor="#007bff" />
</Background>
); }

React Native Can't set margin after image

Why can't I separate the last two components?
First, I tried to set justifyContent, but it did not work.
Then, I tried to set margin. It works for title and image, but not for components after Image
I think is because I'm setting image height, but without it image will not appear
import React, {useState, useEffect} from 'react';
import {View, Text, Image, StyleSheet} from 'react-native';
const Card = ({ evento }) => {
return (
<View style={styles.card_container}>
<Text style={styles.titulo}>
{evento.titulo} - R$ {evento.valor}
</Text>
<Image
style={styles.img}
source={{uri: 'https://via.placeholder.com/150'}}
/>
<Text styles={styles.descricao}>{evento.descricao}</Text>
<Text styles={styles.guia}>Organizador: {evento.guia}</Text>
</View>
);
};
const styles = StyleSheet.create({
card_container: {
// flex: 1,
// display: 'flex',
// flexDirection: 'column',
// justifyContent: 'space-between',
fontFamily: 'Rubik-Light',
margin: 3,
marginBottom: 15,
padding: 10,
borderRadius: 10,
backgroundColor: '#ffffff',
elevation: 1,
},
titulo: {
fontFamily: 'Rubik-Medium',
margin: 10,
},
img: {
//alignSelf: 'center',
width: 350, //TODO tamanho dinĂ¢mico
height: 200,
marginBottom: 10, // word
},
descricao: {
marginBottom: 10,
},
guia: {
marginTop: 10
}
});
export default Card;
It's a typo on the Text component. It should be style for the prop in Text component not styles. Here are the correct codes for the last two components.
<Text style={styles.descricao}>{evento.descricao}</Text>
<Text style={styles.guia}>Organizador: {evento.guia}</Text>

How to hide the react native focus input border?

There would be always a blue border when the text focus. I have already set style borderWidth: 0, but there is still a border. I also tried to set the border color, it won't work either.
Any hint?
Nothing special, I starts from expo tab boilerplate.
Also I found the autofocuse won't be able to triggered either :(
import * as React from "react";
import { StyleSheet } from "react-native";
import { TextInput } from "react-native-gesture-handler";
import EditScreenInfo from "../components/EditScreenInfo";
import { Text, View } from "../components/Themed";
export default function TabOneScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>Tab One</Text>
<View
style={styles.separator}
lightColor="#eee"
darkColor="rgba(255,255,255,0.1)"
/>
<TextInput
autoFocus={true}
placeholder="here is a input"
style={{ padding: 4, borderBottomWidth: 2 }}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
title: {
fontSize: 20,
fontWeight: "bold",
},
separator: {
marginVertical: 30,
height: 1,
width: "80%",
},
});
Can you try setting outlineStyle to 'none'. This will remove all border styles
<TextInput style={{outlineStyle: 'none' }} />

React Native Reusable Card Component won't Visualize as expected

Hello there I'm new to react native. I'm trying to create reusable component, not only card component, maybe in future will create other reusable components. Below is the code example of reusable card component that I've created:
Card.js
import React from 'react';
import { View, StyleSheet } from 'react-native';
const Card = props => {
return (
<View style={{...styles.card, ...props.style}}>{props.children}</View>);};
const styles = StyleSheet.create({
card: {
shadowColor: 'black',
shadowOffset: { width: 0, height: 2 },
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 8,
backgroundColor: 'white',
padding: 20,
borderRadius: 10,
}
});
export default Card;
StartGameScreen.js
import React from 'react';
import { View, Text, StyleSheet, TextInput, Button } from 'react-native';
import Card from '../components/Card';
const StartGameScreen = props => {
return (
<View style={styles.screen}>
<Text style={styles.title}>Start a New Game!</Text>
<Card style={styles.inputContainer}>
<Text>Select a Number</Text>
<TextInput />
<View style={styles.buttonContainer}>
<View style={styles.button}><Button title="Reset" onPress={() => {}} /></View>
<View style={styles.button}><Button title="Confirm" onPress={() => {}} /></View>
</View>
</Card>
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
padding: 10,
alignItems: 'center'
},
title: {
fontSize: 20,
marginVertical: 10
},
inputContainer: {
width: 300,
maxWidth: '80%',
alignItems: 'center'
},
buttonContainer: {
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
paddingHorizontal: 15
},
button: {
width:100
}
});
export default StartGameScreen;
The Result as below:
I'm expecting it to be as below:
Is it possible to use my above code and have the expected result? or is my code wrong and there is better solution??
Your card component is reusable only mistake is the way you are merging the styles. When you merge styles you should not expand it but use an array of styles. Like below.
const Card = props => {
return (<View style={[styles.card, props.style]}>{props.children}</View>);
};
You can check the below snack for full code.
https://snack.expo.io/#guruparan/e368b9

ScrollView steps over parent element while no flex but can not be seen with flex

I'm currently doing an example of a Model View with a label and a ScrollView below it. However, in the ScrollView's style when I set with no flex it goes over the parent element.
https://i.imgur.com/VGZ6vll.png
While if I set flex: 1 to the ScrollView style, the content does not show on the screen.
https://i.imgur.com/9e00ydF.png
Here is my code:
App.js:
import React, { Component } from "react";
import { Text, TouchableOpacity, View } from "react-native";
import Modal from "react-native-modal";
import ModalContent from './src/ModalContent';
export default class ModalTester extends Component {
state = {
isModalVisible: false
};
_toggleModal = () =>
this.setState({ isModalVisible: !this.state.isModalVisible });
render() {
return (
<View style={{ flex: 1 }}>
<TouchableOpacity onPress={this._toggleModal}>
<Text>Show Modal</Text>
</TouchableOpacity>
<Modal
isVisible={this.state.isModalVisible}
onBackdropPress={() => this.setState({ isModalVisible: false })}
>
<View style={styles.modalStyle}>
<ModalContent />
</View>
</Modal>
</View>
);
}
}
const styles = {
modalStyle: {
flex: 1,
marginTop: 20,
marginBottom: 20,
marginLeft: 10,
marginRight: 10,
backgroundColor: "#fff",
}
}
ModalContent.js:
import React from 'react';
import { View, Text, ScrollView } from 'react-native';
import InfoBox from './InfoBox'
export default () => {
return (
<View styles={styles.containerStyle}>
<Text style={styles.headerStyle}>TRIP INFO</Text>
<ScrollView style={styles.scrollViewStyle}>
<InfoBox boxHeight={100} />
<InfoBox boxHeight={200} />
<InfoBox boxHeight={400} />
</ScrollView>
</View>
);
}
const styles = {
containerStyle: {
flex: 1,
marginTop: 20,
marginBottom: 20,
marginLeft: 10,
marginRight: 10,
backgroundColor: "#fff",
},
headerStyle: {
fontSize: 35,
fontFamily: 'OpenSans',
fontWeight: 'bold',
color: '#be5bc2',
marginTop: 10,
marginLeft: 10,
},
scrollViewStyle: {
marginTop: 10,
}
}
InfoBox.js:
import React from 'react';
import { View, Text } from 'react-native';
export default ({boxHeight}) => {
setContainerStyle = function(setHeight) {
return ({
borderWidth: 1,
borderRadius: 4,
borderColor: "#000",
height: setHeight,
marginTop: 25,
marginLeft: 20,
marginRight: 20,
});
}
return (
<View style={this.setContainerStyle(boxHeight)}>
<Text>Hello</Text>
</View>
);
};
I have the same issue and change style for contentContainerStyle in ScrollView and works for me.
It would look like this:
<ScrollView contentContainerStyle={{ marginTop: 10 }} />