I might have asked this question in a confusing way, so I apologize. But I have a map function that renders a lot of text elements dynamically and also styles them based on state. However, the calculations used to create the elements in the first place seems really expensive performance-wise. So I would like to render them once, and then store the created elements in state, and yet still have the styling rerender when it needs to.
I tried storing these mapped elements in an array, but the styling variables inside of each component are set to a single value when the component is stored. So rerendering the page doesn’t change the styling of these components even if the initial variables used to set their styles in state have changed.
import React, {useState} from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default function App() {
let [redText, setRedText] = useState(['This', 'That'])
let [blueText, setBlueText] = useState(['The', 'Other'])
let str = 'This That And The Other'
let arr = str.split(" ")
let componentsArr = null
function firstRender() {
componentsArr = []
componentsArr.push(arr.map((el) => {
return (
<View style={styles.container}>
<Text style={redText.includes(el)
? styles.redText
: blueText.includes(el)
? styles.blueText
: styles.blackText}>
{el}
</Text>
</View>
)
}))
return componentsArr
}
return (
<View style={styles.container}>
{componentsArr ? componentsArr : firstRender()}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
blackText: {
color: "black"
},
redText: {
color: "red"
},
blueText: {
color: "blue"
}
});
Let’s say I have some code like this that adds an onPress event to each element that will automatically change it to red. How can I do that without mapping through and creating the View and Text components from scratch?
When it is initially pushed into the array, all of the styling variables are set in stone. Is there some way to preserve the ternary operations?
2
Answers
i’m not sure i understand well what you wanted to do but as i understood, every word in the text must manage it’s own toggle color ? So here how i would go.
Inside CustomTextColorToggle you can wrap the
View
with aPressable
to change the color usingsetColor
This sounds like a good use case for memoization. If you want to prevent rendering of the list and its elements, unless styles change, you need to apply this in two places, the
<View/>
wrapper containingel
and the entire list itself. Below is how I would apply it.Since I’m unsure if you want to change styles from onpress events, or from a general state coming from a higher component, I’ve included both in this example. In addition, depending on your use case, you can modify this above, and test where you need memoization or not since adding it does add extra overhead if its not necessary.
As a note though, the only way to prevent the list from re-rendering at all (only once on mount), is to manage the styles in a local component
In this case, removing
redText
andblueText
from the App component, and removing the props on every component down the tree. From there, you can manage the styles inside theViewItem
component. Should this be the case, you can also remove thememo
function. Below is an example.