import { useRef, useState } from "react";
import { View, StyleSheet, Button, Text } from "react-native";
const CustomButton = (props) => {
const renderCounter = useRef(0);
renderCounter.current = renderCounter.current + 1;
return (<View style={styles.button_wrapper}>
<Button {...props} title="Toggle Color" color={"mediumseagreen"} />
<Text style={styles.render_text}>Render Count: {renderCounter.current}</Text>
</View>)
}
const CustomItem = ({ backColor }) => {
const renderCounter = useRef(0);
renderCounter.current = renderCounter.current + 1;
return (<View style={styles.item}>
<Text style={[{ backgroundColor: backColor }, styles.item_text]}>Sibling Component</Text>
<Text>Render Count:{renderCounter.current}</Text>
</View>)
}
export default function App() {
const [backColor, setBackColor] = useState("crimson")
return (<View style={styles.body}>
<CustomButton onPress={() => { setBackColor(val => val == "crimson" ? "dodgerblue" : "crimson") }} />
<CustomItem backColor={backColor} />
</View>)
}
const styles = StyleSheet.create({
body: {
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
backgroundColor:"ghostwhite"
},
button_wrapper: {
width: "50%",
margin: 10
},
item: {
flex: 1,
height: 80,
margin: 10,
borderRadius: 5,
justifyContent: "center",
alignItems: "center"
},
item_text: {
height: 50,
width: "100%",
borderRadius: 5,
color: "white",
fontWeight: "bold",
textAlign: "center",
textAlignVertical: "center",
},
render_text: {
textAlign: "center",
marginTop: 5
}
});
import { useRef, useState } from "react";
const CustomButton = (props) => {
const renderCounter = useRef(0);
renderCounter.current = renderCounter.current + 1;
return (
<div style={styles.button_wrapper}>
<input type="button" {...props} value="Toggle Color"/>
<div style={styles.render_text}> Render Count: {renderCounter.current} </div>
</div>
);
};
const CustomItem = ({ backColor }) => {
const renderCounter = useRef(0);
renderCounter.current = renderCounter.current + 1;
return (
<div style={styles.item}>
<div style={{ backgroundColor: backColor, ...styles.item_text }}> Sibling Component </div>
<div>Render Count:{renderCounter.current}</div>
</div>
);
};
export default function App() {
const [backColor, setBackColor] = useState("crimson");
return (
<div style={styles.body}>
<CustomButton onClick={() => { setBackColor((val) => (val == "crimson" ? "dodgerblue" : "crimson")) }} />
<CustomItem backColor={backColor} />
</div>
);
}
const styles = {
body: {
display: "flex",
alignItems: "center"
},
button_wrapper: {
width: "50%",
display: "flex",
flexDirection: "column",
margin: 10
},
item: {
display: "flex",
flexDirection: "column",
flex: 1,
margin: "10px",
justifyContent: "center",
alignItems: "center"
},
item_text: {
width: "100%",
padding: "0.5rem",
borderRadius: 5,
color: "white",
textAlign: "center"
},
render_text: {
textAlign: "center",
marginTop: "10px"
}
};
Optimized method (Bottom part of gif)
import { forwardRef, useImperativeHandle, useRef, useState } from "react";
import { View, StyleSheet, Button, Text } from "react-native";
const CustomButton = (props) => {
const renderCounter = useRef(0);
renderCounter.current = renderCounter.current + 1;
return (<View style={styles.button_wrapper}>
<Button {...props} title="Toggle Color" color={"mediumseagreen"} />
<Text style={styles.render_text}>Render Count: {renderCounter.current}</Text>
</View>)
}
const CustomItem = forwardRef((props, ref) => {
const [backColor, setBackColor] = useState("crimson")
const renderCounter = useRef(0);
renderCounter.current = renderCounter.current + 1;
useImperativeHandle(ref, () => ({
toggleColor() {
setBackColor(val => val == "crimson" ? "dodgerblue" : "crimson")
}
// or
//
// toggleColor: ()=>{
// setBackColor(val => val == "crimson" ? "dodgerblue" : "crimson")
// }
}), []);
return (<View style={styles.item}>
<Text style={[{ backgroundColor: backColor }, styles.item_text]}>Sibling Component</Text>
<Text>Render Count: {renderCounter.current}</Text>
</View>)
})
export default function App() {
const itemRef = useRef()
return (<View style={styles.body}>
<CustomButton onPress={() => { itemRef.current.toggleColor() }} />
<CustomItem ref={itemRef} />
</View>)
}
const styles = StyleSheet.create({
body: {
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
backgroundColor: "ghostwhite"
},
button_wrapper: {
width: "50%",
margin: 10
},
item: {
flex: 1,
height: 80,
margin: 10,
borderRadius: 5,
justifyContent: "center",
alignItems: "center"
},
item_text: {
height: 50,
width: "100%",
borderRadius: 5,
color: "white",
fontWeight: "bold",
textAlign: "center",
textAlignVertical: "center",
},
render_text: {
textAlign: "center",
marginTop: 5
}
});
import { forwardRef, useImperativeHandle, useRef, useState } from "react";
const CustomButton = (props) => {
const renderCounter = useRef(0);
renderCounter.current = renderCounter.current + 1;
return (<div style={styles.button_wrapper}>
<input type="button" {...props} value="Toggle Color" />
<div style={styles.render_text}> Render Count: {renderCounter.current} </div>
</div>);
}
const CustomItem = forwardRef((props, ref) => {
const [backColor, setBackColor] = useState("crimson");
const renderCounter = useRef(0);
renderCounter.current = renderCounter.current + 1;
useImperativeHandle(ref, () => ({
toggleColor() {
setBackColor(val => val == "crimson" ? "dodgerblue" : "crimson")
}
// or
//
// toggleColor: ()=>{
// setBackColor(val => val == "crimson" ? "dodgerblue" : "crimson")
// }
}), []);
return (<div style={styles.item}>
<div style={{ backgroundColor: backColor, ...styles.item_text }}> Sibling Component </div>
<div>Render Count:{renderCounter.current}</div>
</div>);
})
export default function App() {
const itemRef = useRef()
return (<div style={styles.body}>
<CustomButton onClick={() => { itemRef.current.toggleColor() }} />
<CustomItem ref={itemRef} />
</div>);
}
const styles = {
body: {
display: "flex",
alignItems: "center"
},
button_wrapper: {
width: "50%",
display: "flex",
flexDirection: "column",
margin: 10
},
item: {
display: "flex",
flexDirection: "column",
flex: 1,
margin: "10px",
justifyContent: "center",
alignItems: "center"
},
item_text: {
width: "100%",
padding: "0.5rem",
borderRadius: 5,
color: "white",
textAlign: "center"
},
render_text: {
textAlign: "center",
marginTop: "10px"
}
};
Resources: