The biggest question is how to manage and update the state of this component internally through the DOM without using the useState hook? How to do re-rendering?
I've been researching a lot on the Internet, but what I see most is the use of a component that is already native and has a ready-made implementation like TextInput, and there's no way to know how these components do this. In the case of CheckBox, most searches return a controlled component. I only found it for pure React because it has the native component that by default is not controlled.
Update:
My research led to the conclusion that an uncontrolled component does use the "useState" state because it is only possible to re-render through it. The difference is that in the uncontrolled component this state is created and managed internally by the component itself. Making it so that only that component does the re-rendering. So the answer I found to the first and second questions is no. It is not possible to create an uncontrolled component that does re-rendering without using "useState". Mahammad Momin's answer, in addition to helping me, was the most accurate according to my research and that's why I'll take it for granted.
import React, { useRef } from 'react';
import { View, Text, TouchableWithoutFeedback, StyleSheet } from 'react-native';
const UncontrolledCheckbox = ({ label, onChange }) => {
const isCheckedRef = useRef(false);
const toggleCheckbox = () => {
isCheckedRef.current = !isCheckedRef.current;
onChange?.(isCheckedRef.current); // Notify parent if needed
forceUpdateUI(); // Trigger UI re-render
};
const [visualState, setVisualState] = React.useState(false); // Only for UI re-render
const forceUpdateUI = () => setVisualState((prev) => !prev);
return (
<TouchableWithoutFeedback onPress={toggleCheckbox}>
<View style={styles.container}>
<View
style={[
styles.checkbox,
isCheckedRef.current && styles.checkboxChecked,
]}
/>
<Text style={styles.label}>{label}</Text>
</View>
</TouchableWithoutFeedback>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
marginVertical: 5,
},
checkbox: {
width: 20,
height: 20,
borderWidth: 2,
borderColor: '#000',
marginRight: 10,
},
checkboxChecked: {
backgroundColor: '#007BFF',
},
label: {
fontSize: 16,
},
});
export default UncontrolledCheckbox;