web-dev-qa-db-fra.com

Puis-je créer des styles dynamiques dans React Native?

Disons que j'ai un composant avec un rendu comme celui-ci:

<View style={jewelStyle}></View>

Où jewelStyle = 

  {
    borderRadius: 10,
    backgroundColor: '#FFEFCC',
    width: 20,
    height: 20,
  },

Comment puis-je rendre la couleur de fond dynamique et attribué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?

88
Pete Thorne

Je fais habituellement quelque chose comme:

<View style={this.jewelStyle()} />

...

jewelStyle = function(options) {
   return {
     borderRadius: 12,
     background: randomColor(),
   }
 }

Chaque fois que View est rendu, un nouvel objet de style est instancié avec une couleur aléatoire qui lui est associée. Bien entendu, cela signifie que les couleurs changeront chaque fois que le composant sera rendu, ce qui n'est peut-être pas ce que vous voulez. Au lieu de cela, vous pourriez faire quelque chose comme ceci:

var myColor = randomColor()
<View style={jewelStyle(myColor)} />

...

jewelStyle = function(myColor) {
   return {
     borderRadius: 10,
     background: myColor,
   }
 }
132
Jimmie Berg

Oui, 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;

Et alors:

<Header title="HOME" style={ {backgroundColor: '#10f1f0'} } />
50
diegoprates

Si vous souhaitez toujours tirer parti de StyleSheet.create et avoir également 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 que la propriété style de View est définie en tant que tableau combinant votre feuille de style avec vos styles dynamiques.

14
Carlos Atencio

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
  }
  });
7
Yogesh Lolusare

Vous voudrez quelque chose comme ça:

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 de lignes, contenant les données des lignes du composant, et le mappe dans un tableau de composants Text. J'utilise des styles en ligne pour appeler la fonction getRandomColor chaque fois que je crée un nouveau composant Texte.

Le problème avec votre code est que vous définissez le style une fois et que, par conséquent, getRandomColor n’est appelé qu’une fois, lorsque vous définissez le style.

4
Colin Ramsay

Le plus facile est le mien:

<TextInput style={styles.default, [
  this.props.singleSourceOfTruth ?
  {backgroundColor: 'black'} : {backgroundColor: 'white'}
]}/>
2
Not Exactly

Je sais qu'il existe plusieurs réponses, mais je pense que la meilleure et la plus simple consiste à 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>
          ...
       )
    }

}

1
Cesar Alonso

Oui, vous pouvez créer des styles dynamiques. Vous pouvez transmettre 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,
      }
    })
  }
}

puis utilisez-le dans votre composant de 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>
    );
  }
}
0
Rajesh Nasit

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>
 );
 }
}
0
Hossam Ghareeb

Au cas où quelqu'un aurait besoin d'appliquer des conditions

 selectedMenuUI = function(value) {
       if(value==this.state.selectedMenu){
           return {
                flexDirection: 'row',
                alignItems: 'center',
                paddingHorizontal: 20,
                paddingVertical: 10,
                backgroundColor: 'rgba(255,255,255,0.3)', 
                borderRadius: 5
           }  
       } 
       return {
            flexDirection: 'row',
            alignItems: 'center',
            paddingHorizontal: 20,
            paddingVertical: 10
       }
    }
0
shankey

L'utilisation de l'opérateur de propagation d'objet "..." a fonctionné pour moi:

<View style={{...jewelStyle, ...{'backgroundColor': getRandomColor()}}}></View>
0
Cem Roso

Si vous utilisez un écran avec des filtres, par exemple, et que vous souhaitez définir l’arrière-plan du filtre en fonction de sa sélection ou non, vous pouvez procéder comme suit:

<TouchableOpacity style={this.props.venueFilters.includes('Bar')?styles.filterBtnActive:styles.filterBtn} onPress={()=>this.setFilter('Bar')}>
<Text numberOfLines={1}>
Bar
</Text>
</TouchableOpacity>

Sur quel ensemble de filtre 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 de redux et this.props.venueFilters est un état de redux.

0
FrikLima