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
CSS Display: Inline-Block Does Not Accept Margin-Top
Absolute Positioning Inside Relative Positioning
Safari and Ie Can't Read Ttf and Eot Fonts
Print Background Image in Ie Without Enable "Print Background Colors and Images"
When Does Flex-Grow Switch to Flex-Shrink, and Vice-Versa
What CSS3 Features Still Need Vendor Prefixes
My Z-Index Property Is Not Getting Set
How to Position a Div in the Middle of the Screen When the Page Is Bigger Than the Screen
How to Draw a Checkmark/Tick Using CSS
Twitter Bootstrap: Center Text on Progress Bar
Css: Transition Opacity on Mouse-Out
CSS Negative Z-Index: What Does It Mean
Css3 Gradient Rendering Issues from Transparent to White
How to Hide Element Label by Element Id in CSS
How to Make an Element Inherit a Set of CSS Rules for Another Element