React native styles not combining - javascript

I am trying to pass the fontSize as a style property to my component. The fontSize doesnt change any ideas how I can pass the fontSize as a prop to overwrite the default size?
<Homemenu navigation={navigation} style={styles.homeMenu} />
const styles = StyleSheet.create({
....
homeMenu: {
fontSize: 16,
},
});
In my homeMenu:
render() {
let {style, navigation} = this.props;
let fontSize = style && style.fontSize ? style.fontSize : null;
return (
<View style={styles.container}>
<View style={[styles.menuItem, fontSize]}>
....
</View>
const styles = StyleSheet.create({
...
menuItem: {
fontSize: 26
},
});

I guess you are unnecessary bother for falsy values in style prop. I don't see any issue of why it shouldn't work. Code looks good to me.
<Homemenu navigation={navigation} style={styles.homeMenu} />
const styles = StyleSheet.create({
...
homeMenu: {
fontSize: 16,
},
});
render() {
let { style, navigation } = this.props;
return (
<View style={styles.container}>
<View style={[styles.menuItem, style]}>
....
</View>
</View>
);
}
const styles = StyleSheet.create({
...
menuItem: {
fontSize: 26
},
});

You are doing it correct, the only change you need to make in
<View style={[styles.menuItem, fontSize]}>
is you should update the existing style object
style={{...styles.menuItem, fontSize}}
Basically it should be iterable, so that your second value can overrride the first one. And we should not enclose it with square brackets and we should use curly braces, since it is object.

Related

How to add dynamic width and color to a view in react native?

I am trying to adjust the width of a view and color according to a variable. I initially declare the variable inside the app which doesnt seem to work. I have also tried declaring the variable outside the function scope but doesnt register. Is there anyway I could dynamically edit the width of the child using the declared variable? Or is there a function that allows me to do this?
const app = () =>{
const childWidth = 50;
const viewColor = 'red'
return(
<View style={styles.parent}>
<View style={styles.child}>CHILD</View>
</View>
)}
styles = styleSheet.create({
parent:{
width: 100,
color: 'white',
},
child:{
width: {childWidth},
color: {viewColor},
}
})
Thanks in advance
I am assuming you want to edit the width dynamically so let's change it using an InputText.
first let's create our useState hook.
const myFunc = () =>{
const [width , setWidth] = useState("50px")
return(
<>
<TextInput onChangeText={setWidth}
value={width} />
//let's assume you want to change the width of this element.
<element style={{width : {width} }}
</>
)
export default ...
i suggest you can use styles in condition
const app = () =>{
const isChildOneStyle = true
return(
<View style={styles.parent}>
<View style={isChildOneStyle ? styles.child1 : styles.child2}>CHILD</View>
</View>
)}
styles = styleSheet.create({
parent:{
width: 100,
color: 'white',
},
child1:{
width: 50,
color: 'red',
},
child2:{
width: 80,
color: 'green',
},
})
or you can overrite style
const app = ({customStyles}) =>{
return(
<View style={styles.parent}>
<View style={[styles.child, customStyles]}>CHILD</View>
</View>
)}
or if you retreived this parameters from api you can do like this
const app = ({customWidth, customColor}) =>{
return(
<View style={styles.parent}>
<View style={[styles.child, { width :customWidth , color: customColor }]}>CHILD</View>
</View>
)}

How do I pass a prop to a stylesheet in React Native?

I have a prop called isProfile which is used by a component (Feed) that uses the stylesheet below. I want to conditionally render the height of the container based on whether the isProfile prop is set as true or false.
function Feed({isProfile}){
return(
<View style={style.container}>
</View>
)
}
const styles = StyleSheet.create({
container:{
backgroundColor:colors.primary,
width:windowWidth,
justifyContent:"center",
height: isProfile ? windowHeight : windowHeight*0.87,
},
You should change styles to a function that accepts the parameter:
function Feed({isProfile}){
return(
<View style={createStyles(isProfile).container}>
</View>
)
}
const createStyles = (profile) => StyleSheet.create({
container:{
backgroundColor:colors.primary,
width:windowWidth,
justifyContent:"center",
height: profile ? windowHeight : windowHeight*0.87,
},
The isProfile variable (prop) is local to the component and invisible outside, so it must be passed as the parameter
You can store mutiple styles by using an array of objects for style style={[{},{}]} etc.. This allows you to add the second part I added
function Feed({isProfile}){
return(
<View style={[style.container,{height: isProfile ? windowHeight : windowHeight*0.87,}]}>
</View>
)
}
const styles = StyleSheet.create({
container:{
backgroundColor:colors.primary,
width:windowWidth,
justifyContent:"center",
},

Share state between components

I am working on a hobby gym management app, and I am puzzled by the mechanism of sharing state between three components in React-Native.
My three components are:
1. Schedule:
[...]
function Schedule() {
return (
<Stack.Navigator
initialRouteName="Monday"
screenOptions={{
headerStyle: { backgroundColor: "#f58220" },
headerTintColor: "#fff",
headerTitleStyle: { fontWeight: "bold" },
headerRight: () => <SwitchButton />,
}}
>
<Stack.Screen
name="TabStack"
component={TabStack}
options={{ title: "Aerobic Schedule" }}
/>
</Stack.Navigator>
);
}
export default Schedule;
I want the SwitchButton button in my Schedule component (1.) to alternate between DATA_AEROBIC and DATA_KIDS arrays props of the FlatList in (2.) based on the content of the listAerobic boolean variable.
2. MondayPage:
[...]
const MondayPage = () => {
const [selectedId, setSelectedId] = useState(null);
const [listAerobic, setListAerobic] = useState(true);
const renderItem = ({ item }) => {
const backgroundColor = item.id === selectedId ? "#6e3b6e" : "#f9c2ff";
return (
<Item
item={item}
onPress={() => setSelectedId(item.id)}
style={{ backgroundColor }}
/>
);
};
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={{ flex: 1, padding: 5 }}>
<SafeAreaView style={styles.container}>
<FlatList
data={listAerobic ? DATA_AEROBIC : DATA_KIDS}
renderItem={renderItem}
keyExtractor={(item) => item.id}
extraData={selectedId}
/>
</SafeAreaView>
</View>
</SafeAreaView>
);
};
However, I don't know how to link the listAerobic boolean variable to the state of the SwitchButton component (3.) , and how to make it toggle on and off.
3. SwitchButton:
const SwitchButton = () => {
const [isEnabled, setIsEnabled] = useState(false);
const toggleSwitch = () => setIsEnabled(previousState => !previousState);
return (
<View style={styles.container}>
<Switch
trackColor={{ false: "#767577", true: "#81b0ff" }}
thumbColor={isEnabled ? "#f5dd4b" : "#f4f3f4"}
ios_backgroundColor="#3e3e3e"
onValueChange={toggleSwitch}
value={isEnabled}
/>
<Text> aerobic/kids</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
marginRight: 5,
padding: 5,
}
});
export default SwitchButton;
Any guidance would be awesome! I mention I have really tried to look it up on different tutorials, but I can't seem to get the gist of it. It is my first project in React/React-Native.
Many thanks!
I think you just need 'value' to accept a prop passed into it on the switch button. Then wherever you use switch button just pass a boolean value into it from state e.g.
<SwitchButton enabled={this.state.switchEnabled}/>
As for setting state 'globally' so this.state.switchEnabled can be updated from various places / accessible all over the app you need to look into state management tools like Redux (or I hear 'React Hooks' is now a thing and preferred....)

Create rows in React Native

i want to create rows for images,which recieve from _find function.This function already seperated array to subarrays,which number equals number of rows,how i can render rows with data from _find?Dont purpose ready solutions such as react-native-easy-grid,i want to do it without another libs,and can i scroll items if i use this way?
import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View,StyleSheet,Button,Image,ScrollView,Dimensions,ListView } from 'react-native';
import Grid from './GridBuilder.js';
const regUrl = /(src=")?(https:\/\/\S{2,500})(")/gm;
var IMAGES_PER_ROW = 3;
let app1;
export default class inputText extends Component {
constructor(props) {
super(props);
app1 = this;
this.state = {
text: null,
findEvent:false,
im_p_r:3,
items:{},
};
}
render() {
return (
<View style={{margin: 20}}>
<TextInput
style = {styles.searchInput}
placeholder="Type here to search"
onChangeText={(text) => this.setState({text})}
/>
<Button
onPress={() => this._find(this.state.text)}s
title='Find'
color="#841584"
accessibilityLabel="on"
/>
{this.state.findEvent && <DisplayImage />}
</View>
);
}
_find(searchText){
fetch('https://www.googleapis.com/customsearch/v1?key=AIzaSyAfcN3jfimFxHxpHNjhHOSuuY8dm5YZnqQ&cx=007223195539364418542:lcqjo0djp7k&num=10&q='+ searchText+'&searchType=image')
.then((resp) => resp.json())
.then(function(data) {
let s = data.items;
let SIZE = IMAGES_PER_ROW;
let res = s.reduce((p,c)=>{
if(p[p.length-1].length == SIZE){
p.link.push([]);
}
p[p.length-1].push(c);
return p.link;
}, [[]])
app1.setState({items:res,findEvent:true});
})
}
}
export class DisplayImage extends Component {
render(){
return(
<View style={styles.container}>
{app1.state.items.map((item,index) => <View style={styles.row} ><Image style={[styles.image,styles.box]} source={{uri:item.link}} key={index} /></View>)}
</View>
)
}
}
const styles = StyleSheet.create({
searchInput:{
fontSize:20,
paddingTop:20,
paddingBottom:20
},
image:{
paddingTop:20,
width:100,
height:100,
},
row: {
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
justifyContent: 'space-between'
},
box: {
flex: 1,
height: 100,
width:100,
backgroundColor: '#333',
},
})
AppRegistry.registerComponent('inputText', () => inputText);
AppRegistry.registerComponent('DisplayImage', () => DisplayImage);
You can use FlatList from React Native.
{this.state.findEvent && <FlatList
data={this.state.items}
renderItem={({ item }) => this.renderItem(item)}
/>}
FlatList receive as data the list of elements you want to render, in this case the data returned from the find function.
And then define the renderItem function like:
renderItem(item) {
return (
<View style={styles.row} >
<Image
style={[styles.image,styles.box]}
source={{uri:item.link}} key={index}
/>
</View>
);
}
This function is in charge of rendering the list of images, each image as a row as you want.
FlatList is really useful and makes lists rendering easier. You get the scroll by default and you can also render separators, have a pull to refresh, etc. Take a look to the FlatList doc to see all properties available.
Here is working example of Flat list by which you can get images in the row
https://snack.expo.io/SJDoljDg7
FlatList is the way to go but I suspect the spec has changed since the original accepted answer. You must now provide a key extractor, here is an example of what worked for me:
const listItems = [
{
"id": 0.7967679550647925,
"name": "Hcsrhjkh",
},
{
"id": 0.3212834674770011,
"name": "Phvdgbb",
},
{
"id": 0.30092504022778455,
"name": "Hnvdghbh",
},
]
...
{listItems.length < 1 ? (
<Text style={{ fontSize: 30 }}>Your list is empty.</Text>
) : (
<FlatList
data={listItems}
renderItem={({item}) => <ListItem item={item} />}
keyExtractor={(item) => item.id.toString()}
/>
)}
As you can might have found, the keyExtractor expects a string so I've coerced the 'id' which is a number to a string.

Updating an element of a components style in React Native [duplicate]

This question already has answers here:
Passing Styles Based on Parent Component in React Native
(2 answers)
Closed 5 years ago.
I have a custom component called CardSection
import React from 'react';
import { View } from 'react-native';
const CardSection = (props) => {
return (
<View style={styles.containerStyle}>
{props.children}
</View>
);
};
const styles = {
containerStyle: {
borderBottomWidth: 1,
padding: 5,
backgroundColor: '#fff',
justifyContent: 'flex-start',
flexDirection: 'row',
borderColor: '#ddd',
position: 'relative'
}
};
export { CardSection };
When I instantiate this component from another class I would like to update one of the style elements while the others remain unchanged. The code below will only update the justifyContent element.
<CardSection style={{ justifyContent: 'space-between' }}>
The solution I have at the minute does not seem to be working and I would like to avoid duplicating the element with just a change to one of the style elements.
You could do the following:
//destruct props
const CardSection = ({ style, children }) => {
return (
// prop 'style' overrides standard containerStyle
<View style={[styles.containerStyle, style]}>
{children}
</View>
);
};
You can merge styles if you pass an array to styles:
const CardSection = (props) => {
return (
<View style={[styles.containerStyle, props.style]}>
{props.children}
</View>
);
};
They 'cascade' from left to right, meaning that latter styles in the array overwrite the former.
Here is the documentation for styling in react-native by default.

Categories