Puis-je créer des styles dynamiques dans React Native?
Disons que j'ai un composant avec un rendu comme ceci:
<View style={jewelStyle}></View>
Où jewelStyle =
{
borderRadius: 10,
backgroundColor: '#FFEFCC',
width: 20,
height: 20,
},
Comment puis-je rendre la couleur d'arrière-plan dynamique et assignée au hasard? J'ai essayé
{
borderRadius: 10,
backgroundColor: getRandomColor(),
width: 20,
height: 20,
},
Mais cela fait que toutes les instances de View ont la même couleur, je veux avoir chacune un individu.
Des conseils?
10 réponses
Je fais habituellement quelque chose comme:
<View style={this.jewelStyle()} />
...
jewelStyle = function(options) {
return {
borderRadius: 12,
background: randomColor(),
}
}
Chaque fois que la vue est rendue, un nouvel objet de style sera instancié avec une couleur aléatoire associée. Bien sûr, cela signifie que les couleurs changeront chaque fois que le composant est rendu à nouveau, ce qui n'est peut-être pas ce que vous voulez. Au lieu de cela, vous pouvez faire quelque chose comme ceci:
var myColor = randomColor()
<View style={jewelStyle(myColor)} />
...
jewelStyle = function(myColor) {
return {
borderRadius: 10,
background: myColor,
}
}
Oui, vous pouvez et en fait, vous devriez utiliser StyleSheet.create
pour créer vos styles.
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View
} from 'react-native';
class Header extends Component {
constructor(props){
super(props);
}
render() {
const { title, style } = this.props;
const { header, text } = defaultStyle;
const combineStyles = StyleSheet.flatten([header, style]);
return (
<View style={ combineStyles }>
<Text style={ text }>
{ title }
</Text>
</View>
);
}
}
const defaultStyle = StyleSheet.create({
header: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
height: 60,
paddingTop: 15,
shadowColor: '#000',
shadowOffset: { width: 0, height: 3 },
shadowOpacity: 0.4,
elevation: 2,
position: 'relative'
},
text: {
color: '#0d4220',
fontSize: 16
}
});
export default Header;
Puis:
<Header title="HOME" style={ {backgroundColor: '#10f1f0'} } />
Si vous voulez toujours profiter de StyleSheet.create
et avoir aussi des styles dynamiques, essayez ceci:
const Circle = ({initial}) => {
const initial = user.pending ? user.email[0] : user.firstName[0];
const colorStyles = {
backgroundColor: randomColor()
};
return (
<View style={[styles.circle, colorStyles]}>
<Text style={styles.text}>{initial.toUpperCase()}</Text>
</View>
);
};
const styles = StyleSheet.create({
circle: {
height: 40,
width: 40,
borderRadius: 30,
overflow: 'hidden'
},
text: {
fontSize: 12,
lineHeight: 40,
color: '#fff',
textAlign: 'center'
}
});
Notez comment la propriété style
du View
est définie comme un tableau qui combine votre feuille de style avec vos styles dynamiques.
Avait un problème syntaxiquement. Cela a fonctionné pour moi
<Text style={StyleSheet.flatten([styles.textStyle,{color: 'red'}])}> Hello </Text>
const styles = StyleSheet.create({
textStyle :{
textAlign: 'center',
fontFamily: 'Arial',
fontSize: 16
}
});
Vous voudrez quelque chose comme ceci:
var RandomBgApp = React.createClass({
render: function() {
var getRandomColor = function() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
var rows = [
{ name: 'row 1'},
{ name: 'row 2'},
{ name: 'row 3'}
];
var rowNodes = rows.map(function(row) {
return <Text style={{backgroundColor:getRandomColor()}}>{row.name}</Text>
});
return (
<View>
{rowNodes}
</View>
);
}
});
Dans cet exemple, je prends le tableau rows, contenant les données pour les lignes du composant, et je le mappe dans un tableau de composants de texte. J'utilise des styles en ligne pour appeler la fonction getRandomColor
chaque fois que je crée un nouveau composant de texte.
Le problème avec votre code est que vous définissez le style une fois et donc getRandomColor n'est appelé qu'une seule fois - lorsque vous définissez le style.
Le plus facile est le mien:
<TextInput style={styles.default, [
this.props.singleSourceOfTruth ?
{backgroundColor: 'black'} : {backgroundColor: 'white'}
]}/>
Je sais qu'il y a plusieurs réponses, mais je pense que le meilleur et le plus simple est d'utiliser un État "Changer" est le but de l'état.
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
style: {
backgroundColor: "white"
}
};
}
onPress = function() {
this.setState({style: {backgroundColor: "red"}});
}
render() {
return (
...
<View style={this.state.style}></View>
...
)
}
}
Vous pouvez lier la valeur d'état directement à l'objet style. Voici un exemple:
class Timer extends Component{
constructor(props){
super(props);
this.state = {timer: 0, color: '#FF0000'};
setInterval(() => {
this.setState({timer: this.state.timer + 1, color: this.state.timer % 2 == 0 ? '#FF0000' : '#0000FF'});
}, 1000);
}
render(){
return (
<View>
<Text>Timer:</Text>
<Text style={{backgroundColor: this.state.color}}>{this.state.timer}</Text>
</View>
);
}
}
Si vous utilisez un écran avec des filtres par exemple, et que vous voulez définir l'arrière-plan du filtre en fonction de si elle a été sélectionnée ou non, vous pouvez faire:
<TouchableOpacity style={this.props.venueFilters.includes('Bar')?styles.filterBtnActive:styles.filterBtn} onPress={()=>this.setFilter('Bar')}>
<Text numberOfLines={1}>
Bar
</Text>
</TouchableOpacity>
Sur lequel set filter est:
setVenueFilter(filter){
var filters = this.props.venueFilters;
filters.push(filter);
console.log(filters.includes('Bar'), "Inclui Bar");
this.setState(previousState => {
return { updateFilter: !previousState.updateFilter };
});
this.props.setVenueFilter(filters);
}
PS: la fonction this.props.setVenueFilter(filters)
est une action redux, et this.props.venueFilters
est un État redux.
Oui, vous pouvez créer des styles dynamiques. Vous pouvez passer des valeurs à partir de composants.
Créez D'abord StyleSheetFactory.js
import { StyleSheet } from "react-native";
export default class StyleSheetFactory {
static getSheet(backColor) {
return StyleSheet.create({
jewelStyle: {
borderRadius: 10,
backgroundColor: backColor,
width: 20,
height: 20,
}
})
}
}
Ensuite l'utiliser dans votre composant de la manière suivante
import React from "react";
import { View } from "react-native";
import StyleSheetFactory from './StyleSheetFactory'
class Main extends React.Component {
getRandomColor = () => {
var letters = "0123456789ABCDEF";
var color = "#";
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
render() {
return (
<View>
<View
style={StyleSheetFactory.getSheet(this.getRandomColor()).jewelStyle}
/>
<View
style={StyleSheetFactory.getSheet(this.getRandomColor()).jewelStyle}
/>
<View
style={StyleSheetFactory.getSheet(this.getRandomColor()).jewelStyle}
/>
</View>
);
}
}