How to Make Dynamic Styles in React Native

Can I make dynamic styles in React Native?

I usually do something along the lines of:

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

...

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

Every time View is rendered, a new style object will be instantiated with a random color associated with it. Of course, this means that the colors will change every time the component is re-rendered, which is perhaps not what you want. Instead, you could do something like this:

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

...

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

React native - Change styles dynamically

You can add a style prop to TouchableOpacity and check if this is the selected button like this:

<TouchableOpacity
style={{ borderBottomWidth: this.state.selected === option.code ? 1 : 0 }}
onPress={() => this.setState({ selected: option.code })
>
...
</TouchableOpacity>

Also I guess you can use this.procedureOptionSelected() since you set that option.code in there too!

React Native dynamic styles, adding styles to one element

Your state for tracking the click listClicked is getting shared through all the TouchableOpacity items. If we try to simulate what happens when this.state.ActiveDances.map executes, it returns all the ActiveDances items like:

<TouchableOpacity key=0 style={styles.listItemsDynamicClosed> </TouchableOpacity>
<TouchableOpacity key=1 style={styles.listItemsDynamicClosed> </TouchableOpacity>
<TouchableOpacity key=2 style={styles.listItemsDynamicClosed> </TouchableOpacity>
......

Notice here styles.listItemsDynamicClosed is because of this expression this.state.listClicked ? styles.listItemsDynamicOpen : styles.listItemsDynamicClosed} since this.state.listClicked is still false as you have not clicked yet.

Now when you click and this.state.listClicked is true and since all the TouchableOpacity are sharing it all of them renders as:

<TouchableOpacity key=0 style={styles.listItemsDynamicOpen> </TouchableOpacity>
<TouchableOpacity key=1 style={styles.listItemsDynamicOpen> </TouchableOpacity>
<TouchableOpacity key=2 style={styles.listItemsDynamicOpen> </TouchableOpacity>
......

This is where breaking it into small component comes into play. Imagine if you have one component which is only returning one TouchableOpacity then you could've listClicked applied in only one TouchableOpacity and only the clicked one would update.

//ClickableItem.js
class ClickableItem extends Component {
state = {
listClicked = false,
}

_showListItem = () => {
this.setState({
listClicked: !this.state.listClicked
})

render() {
return(
<TouchableOpacity style={this.state.listClicked ? syles.listItemsDynamicOpen : styles.listItemsDynamicClosed} onPress={this._showListItem}>
...
</TouchableOpacity>
)

}
}

export default ClickableItem

And then in the main/parent component:

//List.js
import ClickableItem from './ClickableItem.js'
class List extends Component {
state = {
ActiveDances: [
{"name":"Agneta & Peter","month":"Jan","day":27,"weekday":"Söndag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Feb","day":23,"weekday":"Fredag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Apr","day":3,"weekday":"Måndag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
]
}

render() {
return(
this.state.ActiveDances.map((ActiveDance, i) => <ClickableItem key={i}>)
)

}
}

Anything data that you need to pass to the children components (ClickableItem in this case) you can pass it down as props and receive it through this.props. More info: https://reactjs.org/docs/components-and-props.html

And since you are new take a look on good practices in javascript codes. One thing I'd like to point out: use camelCase when naming variable references. For react capital case on the beginning of a name should be used for tag/component names only.

I hope it helps you. Welcome to React and React Native :)

How to Dynamically change the style of a react component

As your question asked, I tried to have a sample of making dynamic style which depends, in my case, on the index of the array. Changing colors of the background made me come up with this solution:

App.js

import { Word } from "./word";
//import './typeTest.css'

export default function App() {
const test1 =
"the quick brown fox jumped over a tree and tripped over that tree the quick brown fox jumped over a tree and tripped over that tree the quick brown fox jumped over a tree and tripped over that tree the quick brown fox jumped over a tree and tripped over that tree";
const test1Arr = test1.split(" ");

return (
<div>
<div style={{display:"flex"}}>
{test1Arr.map((monoWord, index) => (
<Word
inputWord={monoWord}
style={{
background: `#${(index*2).toString(16)}${index.toString(16)}${((index+1)/2).toString(16)}`
}}
/>
))}
<Word inputWord="Scoll" />
</div>
</div>
);
}

word.js

export const Word = (props) => {
return <h1 style={props.style}>{props.inputWord}</h1>;
};

As you can see in the word.js component we get the props of style, which is applied later to the child component. Passing the background is the most visible change in styles, so I implemented that. The same technique you would use if you implement a className, which is conditionally writable as string. Here is the example in sandbox.

React Native Dynamic Styling

You'll need to keep in state whether or not your coin has decreased recently.
Imagine a state of this shape:

state = {
hasIncreased: boolean,
hasDecreased: boolean,
}

Now you can change this state in the componentWillReceiveProps (this is now deprecated though, so if you are on 16.3 or higher, maybe look in phasing its use out) like so:

componentWillReceiveProps(nextProps) {
if (nextProps.coinPrice < this.props.coinPrice)
this.setState({hasDecreased: true, hasIncreased: false})

if (nextProps.coinPrice > this.props.coinPrice)
this.setState({hasIncreased: true, hasDecreased: false})
}

Now that you have this state, you can add some styles conditionally:

render() {
const {hasIncreased, hasDecreased} = this.state
return (
<View style={[ //styles can be an array!
upperRow,
hasIncreased && {backgroundColor: 'green'},
hasDecreased && {backgroundColor: 'red'},
]}/>
)
}

Now all that's left is to reset state after 2 seconds. To me, it seems best to use the componentDidUpdate-lifecycle for that

componentDidUpdate(prevProps) {
// only queue the reset if it's actually necessary, not on random updates
if (prevProps.coinPrice !== this.props.coinPrice) {
clearTimeout(this.timeout)
// we need to be able to reset the timeout
this.timeout = setTimeout(
() => this.setState({hasDecreased: false, hasIncreased: false}),
2000,
)
}
}

You should try avoiding just changing the styles like that in a mutable manner. The whole point is that your state should reflect what you display.

How to set props fro dynamic value in styles in react native

You cannot dynamically assign values to StyleSheet properties. Instead, you can try something like this:

<View style={[ styles.CardMainView, {backgroundColor: this.props.colorCode} ]}>

Don't forget to remove backgroundColor: this.props.colorCode from CardMainView.

Dynamic styling based on a state

You do not need to have 2 stylesheets.

Consider the following code:

  constructor(props){
super(props);
this.state = {
snackbar: true,
}
Snackbar.addEventListener('show', () => {this.setState({snackbar:true})})
Snackbar.addEventListener('hidden', () => {this.setState({snackbar:false})})
}

render() {
const fabPositionStyle = this.state.snackbar ? styles.pushUp : styles.normal

return <ActionButton
onPress={() => {this.props.nav.push(routes.takePicture)}}
style={[ styles.fab, fabPositionStyle ]}
/>;
}
}

const styles = StyleSheet.create({
fab: {
height: Dimensions.get('window').width / 9,
width: Dimensions.get('window').width / 9,
backgroundColor: colors.accentColor,
},
pushUp: {
marginBottom: 40,
},
normal: {
marginBottom: 0,
},
})

how can i edit the value of add multiple dynamic form in react class?

i have solve my problem.we have to use defaultValue for solve his problem

<input type="text" defaultValue={this.props.value || ''} />



Related Topics



Leave a reply



Submit