React Native에서 동적 스타일을 만들 수 있습니까?


119

다음과 같은 렌더링이있는 구성 요소가 있다고 가정합니다.

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

여기서 jewelStyle =

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

배경색을 동적으로 만들고 무작위로 할당하려면 어떻게해야합니까? 난 노력 했어

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

그러나 이것은 View의 모든 인스턴스가 동일한 색상을 갖도록 만듭니다. 각 인스턴스가 고유하기를 바랍니다.

팁이 있습니까?

답변:


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()어쨌든 Stylesheet를 선언하는 목적은 무엇입니까 ?
fatuhoku 2015-07-07

2
@fatuhoku 당신이 여러 장소에서 같은 스타일을 다시해야하는 경우를 위해 좋다
Bob9630

4
Stylesheet.create를 사용하면 성능상의 이점이 많이 있습니까?
Dominic

35
@DominicTobias Stylesheet. 팩을 만들고 스타일을 네이티브 영역에 한 번만 "보냅니다". 즉, 동일한 스타일을 여러 번 재사용하거나 동일한 구성 요소를 여러 번로드하면 패킹하고 다시 "보내기"하는 대신 스타일을 재사용하게됩니다. 예를 들어, 3000 개의 스타일이 적용된 행을로드하는 경우 성능이 크게 향상되는 것을 느낄 수 있습니다.
sospedra

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
이 답변의 스타일이 스타일 시트에 정의 보여주는 좋은 예,하지만 구성 요소에 나중에 오버라이드 (override) 할 수 있습니다
bitsand

5
AFAIK를 사용 하면 문서에 명시된대로 StyleSheet.flatten모든 최적화가 삭제 StyleSheet.create됩니다. "참고 :이를 악용하면 최적화 측면에서 부담을 줄 수 있으므로주의하십시오. ID는 일반적으로 브리지와 메모리를 통해 최적화를 가능하게합니다. 스타일 개체를 직접 참조하면 이러한 최적화. " ( facebook.github.io/react-native/docs/stylesheet.html ).
gustavopch 19.06.22

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

훌륭합니다. 정말 훌륭합니다. 이 솔루션으로 속성을 재정의 할 수도 있습니다. 마지막은 이전보다 우선합니다
besil

10

구문 상 문제가있었습니다. 이것은 나를 위해 일했습니다.

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

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

@Yogesh 감사합니다. 이것이 바로 제가 찾고있는 것입니다. 스타일을 사용하면서 필요한 것에 더 추가 할 수 있기를 원합니다.
TLee

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가 한 번만 호출된다는 것입니다.


안녕하세요 Colin, 감사합니다. 다른 스타일 매개 변수를 동시에 전달할 수있는 방법은 무엇입니까?
Pete Thorne

style = {{backgroundColor : getRandomColor (), color : 'black'}} 같은 뜻인가요?
Colin Ramsay

감사합니다. 작동하지만 한 번에 스타일 블록을 전달할 수있는 방법을 보여주는 데 도움이되는 다른 답변을 수락했습니다.
Pete Thorne

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

이것은 임의의 16 진수 색상을 생성합니다. 그런 다음 언제든지 해당 함수를 호출하고 새로운 배경색을 바릅니다.


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.venueFiltersredux 상태입니다.


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

어떤 이유로, 이것이 내 것이 제대로 업데이트되는 유일한 방법이었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.