क्या मैं रिएक्टिव नेटिव में गतिशील स्टाइल बना सकता हूं?


119

कहो कि मेरे पास इस तरह एक रेंडर के साथ एक घटक है:

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

जहँ जहँ जौं सठ =

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

मैं पृष्ठभूमि के रंग को गतिशील और बेतरतीब ढंग से कैसे नियत कर सकता हूं? मैंने कोशिश की

  {
    borderRadius: 10,
    backgroundColor: getRandomColor(),
    width: 20,
    height: 20,
  },

लेकिन यह दृश्य के सभी उदाहरणों का रंग समान है, मैं चाहता हूं कि प्रत्येक अद्वितीय हो।

कोई सुझाव?

जवाबों:


176

मैं आमतौर पर इनकी तर्ज पर कुछ करता हूं:

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

...

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

हर बार देखें जाने पर, एक नई शैली ऑब्जेक्ट को यादृच्छिक रंग से संबद्ध किया जाएगा। बेशक, इसका मतलब है कि हर बार घटक के फिर से प्रस्तुत किए जाने पर रंग बदल जाएगा, जो कि शायद आप क्या चाहते हैं। इसके बजाय, आप ऐसा कुछ कर सकते हैं:

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

...

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

32
यह विधि स्टाइल्सशीट्स का उपयोग बिल्कुल नहीं करती है। Stylesheet.create()वैसे भी स्टाइल्सशीट्स घोषित करने वालों का उद्देश्य क्या है?
फतहोकू

2
@fatuhoku के लिए यह अच्छा है जब आपको कई स्थानों पर एक ही शैली का पुन: उपयोग करने की आवश्यकता होती है
Bob9630

4
वहाँ Stylesheet.create का उपयोग करने के लिए एक बहुत अच्छा लाभ है?
डोमिनिक

35
@DominicTobias Stylesheet.create पैक और शैली को केवल एक बार देशी क्षेत्र में "भेजें"। जिसका मतलब है कि जब आप एक ही शैली का कई बार पुन: उपयोग कर रहे हैं, या एक ही घटक को कई बार लोड कर रहे हैं, तो यह पैकिंग और "भेजने" के बजाय शैली का पुन: उपयोग करने वाला है। उदाहरण के लिए, यदि आप 3000 स्टाइल वाली पंक्तियों को लोड कर रहे हैं, तो आपको पूर्ण रूप से काफी बढ़ावा मिलेगा।
सोसपेडरा

64

हाँ, आप कर सकते हैं और वास्तव में, आपको StyleSheet.createअपनी शैली बनाने के लिए उपयोग करना चाहिए ।

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;

और तब:

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

9
यह उत्तर एक अच्छा उदाहरण दिखाता है जहां एक शैली को स्टाइलशीट में परिभाषित किया गया है, लेकिन बाद में एक घटक में ओवरराइड किया जा सकता है
बिट्सैंड

5
AFAIK का उपयोग करके डॉक्स में बताए अनुसार StyleSheet.flattenसे किसी भी अनुकूलन को फेंक देता है StyleSheet.create: "नोट: इसका दुरुपयोग करने के लिए सावधानी बरतें क्योंकि यह अनुकूलन के मामले में आप पर कर लगा सकता है। आईडी सामान्य रूप से पुल और मेमोरी के माध्यम से अनुकूलन को सक्षम करती है। स्टाइल ऑब्जेक्ट्स को सीधे संदर्भित करना आपको वंचित करेगा। ये अनुकूलन। " ( facebook.github.io/react-native/docs/stylesheet.html )।
गुस्तावोच

27

यदि आप अभी भी लाभ लेना चाहते हैं StyleSheet.createऔर गतिशील शैली भी चाहते हैं, तो इसे आज़माएँ:

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'
    }
});

ध्यान दें कि कैसे की styleसंपत्ति Viewएक सरणी के रूप में सेट की गई है जो आपकी स्टाइलशीट को आपकी गतिशील शैलियों के साथ जोड़ती है।


11

सबसे आसान मेरा है:

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

मैंने @Sarahcartenz टिप्पणी
Marecky

अद्भुत, यह वास्तव में बहुत अच्छा है। एक भी इस समाधान के साथ एक संपत्ति को ओवरराइड कर सकता है, है ना? आखिरी ओवरराइड करता है
12

10

कुछ मुद्दा था। इसने मेरे लिए काम किया

<Text style={[styles.textStyle,{color: 'red'}]}> Hello </Text>

const styles = StyleSheet.create({
   textStyle :{
      textAlign: 'center',   
      fontFamily: 'Arial',
      fontSize: 16
  }
  });

धन्यवाद @Yogesh, यह वही है जिसकी मुझे तलाश है। मैं शैलियों का उपयोग करना चाहता हूं और फिर भी मुझे उन चीजों पर अधिक जोड़ने में सक्षम होना चाहिए जिनकी मुझे आवश्यकता थी।
टीली

4

आप कुछ इस तरह चाहते हैं:

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>
        );

    }
});

इस उदाहरण में मैं पंक्तियों के सरणी को लेता हूं, जिसमें घटक में पंक्तियों के लिए डेटा होता है, और इसे पाठ घटकों की एक सरणी में मैप करता है। getRandomColorजब भी मैं एक नया पाठ घटक बनाता हूं, तो मैं फ़ंक्शन को कॉल करने के लिए इनलाइन शैलियों का उपयोग करता हूं।

आपके कोड के साथ मुद्दा यह है कि आप शैली को एक बार परिभाषित करते हैं और इसलिए getRandomColor केवल एक बार बुलाया जाता है - जब आप शैली को परिभाषित करते हैं।


हाय कॉलिन, इसके लिए धन्यवाद, लेकिन मैं एक ही समय में अन्य शैली मापदंडों में कैसे पारित कर सकता हूं?
पीट थॉर्न

आपका मतलब स्टाइल की तरह है {{{बैकग्राउंडरकलर: getRandomColor (), कलर: 'ब्लैक'}}?
कॉलिन रामसे

धन्यवाद, यह काम करेगा लेकिन मैंने दूसरे उत्तर को स्वीकार कर लिया है क्योंकि यह दिखाता है कि आप एक बार में शैलियों के ब्लॉक को कैसे पारित कर सकते हैं।
पीट थॉर्न

2
मुझे वास्तव में लगता है कि अन्य उत्तर भी बेहतर था :)
कॉलिन रामसे

2

मुझे पता है कि यह बहुत देर हो चुकी है, लेकिन किसी के लिए अभी भी यहाँ एक आसान उपाय है।

तुम सिर्फ शैलियों के लिए एक सरणी बना सकते हैं:

this.state ={
   color: "#fff"
}

style={[
  styles.jewelstyle, {
  backgroundColor: this.state.BGcolor
}

दूसरा किसी भी मूल पृष्ठभूमि रंग को ओवरराइड करेगा जैसा कि स्टाइलशीट में कहा गया है। फिर एक फ़ंक्शन है जो रंग बदलता है:

generateNewColor(){
  var randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);
  this.setState({BGcolor: randomColor})
}

यह एक यादृच्छिक हेक्स रंग उत्पन्न करेगा। तो बस उस फ़ंक्शन को कॉल करें जब भी और बैम, नई पृष्ठभूमि का रंग।


1

मुझे पता है कि कई उत्तर हैं, लेकिन मुझे लगता है कि सबसे अच्छा और सबसे सरल एक राज्य का उपयोग करना है "बदलने के लिए" राज्य का उद्देश्य है।

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

आप स्टाइल ऑब्जेक्ट पर सीधे राज्य मान बाँध सकते हैं। यहाँ एक उदाहरण है:

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

1

हां, आप गतिशील शैली बना सकते हैं। आप कंपोनेंट्स से वैल्यूज पास कर सकते हैं।

सबसे पहले 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,
      }
    })
  }
}

फिर इसे अपने घटक में निम्न तरीके से उपयोग करें

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

1

ऑब्जेक्ट स्प्रेड ऑपरेटर का उपयोग करके "..." ने मेरे लिए काम किया:

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

0

यदि आप उदाहरण के लिए फ़िल्टर के साथ एक स्क्रीन का उपयोग कर रहे हैं, और आप फ़िल्टर के बैकग्राउंड को सेट करना चाहते हैं कि क्या यह चुना गया था या नहीं, तो आप यह कर सकते हैं:

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

किस सेट पर फ़िल्टर है:

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

पुनश्च: फ़ंक्शन this.props.setVenueFilter(filters)एक redux क्रिया है, और this.props.venueFiltersएक redux स्थिति है।


0

मामले में किसी को शर्तें लागू करने की जरूरत है

 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

यहाँ मेरे लिए क्या काम किया गया है:

render() {
  const { styleValue } = this.props;
  const dynamicStyleUpdatedFromProps = {
    height: styleValue,
    width: styleValue,
    borderRadius: styleValue,
  }

  return (
    <View style={{ ...styles.staticStyleCreatedFromStyleSheet, ...dynamicStyleUpdatedFromProps }} />
  );
}

किसी कारण से, यह एकमात्र तरीका था जो मेरा ठीक से अद्यतन करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.