My notes from CodeWithMosh React Native Fundamentals:
- TO START PROJECT:
expo init AppName
<- terminal command to create an app - TO RUN PROJECT:
npm start
will serve app w/ expo - TO DEBUG PROJECT: on phone, shake for dev menu, then hit debug remote JS; opens new tab in chrome, and can use browser console/debugger as normal
View
= div (for grouping or laying out children)- No html elements at all; need to build in react native elements
- Cross-platform: when compiled, React Native compiles these components into their native components for iOS/Android
SafeAreaView
leaves room for iPhone notch; no effect on Android
-Essential text component props:
numberOfLines
= max # of lines to display (excess gets truncated w/ ...)onPress
= event listener; function for what happens when the element is touched- Example:
<Text numberOfLines={1} onPress={handlePress}> Hello React Native! </Text>
- Local images: require function w/ path as source, ex:
source={require('./assets/icon.png')}
<- this tells Metro Bundler to include this file w/ our app (increases size of app, so only use static images where necessary!) - Network images: source w/ object w/ uri, ex:
source={{uri: 'https://picsum.photos/200/300'}}
- for network images, MUST specify dimensions in source obj (width/height) as well as uri before it'll display
loadingIndicatorSource
attribute lets you supply a static local image while the network img is loading- Image component doesn't have onPress! Need to wrap w/ separate touchable component depending on feedback we want to give to users.
- Example:
<TouchableHighlight onPress={handlePress} onLongPress={handleLongPress}> <Image source={{ uri: 'https://picsum.photos/200/300', width: 300, height: 200 }} /> </TouchableHighlight>
- Touchable components have
onPress
andonLongPress
events - Can wrap around elements that don't have their own onPress (like images)
- Three cross-platform touchable components (cross-platform):
TouchableWithoutFeedback
(no feedback when touched)TouchableOpacity
(component goes see-thru when touched)TouchableHighlight
(component goes dark when touched)
- Buttons are self-closing. Text in it is from title prop.
- Props include:
color
<- text colortitle
<- text inside the buttononPress
<- event listener
- Example:
<Button color="orange" title="Click Me" onPress={() => {}} />
- Alert as a function works similarly to browser - pops up a lil window with your message and then ok to close.
- Alert as a component is imported with the other components, but it's an object API with methods (but no visible component, so you can't use it like a normal component, like
<Alert />
) - Two methods: alert() and prompt()
- First argument is the
title
(header for alert box) - Second argument is
message
for the alert body - Third argument is array of buttons; each button is an object with its
text
,style
, andonPress
event
- First argument is the
- Example with basic alert method:
Alert.alert('titleTextHere', 'messageTextHere', [ {text: "button text", onPress: ()=>{}}, {text: "other button text", onPress: ()=>{}} ] )
- Example with prompt method:
Alert.prompt('titleTextHere', 'message', (text)=>{ // fx here that does something w/ the text the user inputted console.log(text) })`
- Passed to component using
style
prop; ex:<SafeAreaView style={styles.container}>
- Styles inside are JS, not CSS!
- Advantages over plain JS object passed to
style
prop:- Validates style properties before passing to components (checks for typos)
- More optimized
- Example:
const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", alignItems: "center", justifyContent: "center", }, });
- Can put where
StyleSheet
is called/used in separate file and then export/import
- Import as
Platform
from react-native - Example:
const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0, //If operating system is Andriod, add padding equiv to status bar height (detected by StatusBar api) }, });
- Import as
StatusBar
from react-native currentHeight
method detects height of status bar
- Physical pixels = DIPs (density-independent pixels) x scale factor of the device <- This is how the app can scale to different screen sizes!
- Can use percentages just like normal CSS; example:
<View style={{ width: '50%' //50% of parent's width, just like normal CSS }}>
- Can import
Dimensions
API from react-nativeget
method takes either"window"
or"screen"
as args and returns object w/ width, height, and scale factor- On iPhone, window === screen, but on Android, screen dimensions are slightly smaller
- Caution: Doesn't respond to orientation changes!!
- Default orientation of app is
"orientation": "portrait"
(inapp.json
); set to"orientation": "default"
instead to be able to be used in both portrait and landscape - React Native Hooks turns React Native APIs into hooks to use w/in functional components
npm i @react-native-community/hooks
import {useDimensions} from '@react-native-community/hooks'
useDimensions
hook returns dimensions of screen whether in portrait or landscape- Returns object w/ fontScale, height, scale, and width
- Component is rerendered when the device is rotated, so the hook gets called again if used w/in the component's code.
useDeviceOrientation
hook returns object w/ landscape and portrait; one will be true, and one will be falseconst {landscape} = useDeviceOrientation()
<-landscape
will be either true or false after every rerender- Then, can use in style obj:
<View style={{ width: '50%', height: landscape ? '100%' : '30%' }}>
- Not exactly the same as CSS flexbox!
flex
property in style object tells the component how much to grow to take available free space.- Shorthand that combines
flexGrow
andflexShrink
- If set to 1, it grows to take all of the free space in the parent element. Example:
const styles = StyleSheet.create({ container: { flex: 1, }, });
- Example w/
flex
set to 0.5 to take half of the parent element's space:const styles = StyleSheet.create({ container: { flex: 0.5, }, });
- If there are multiple items in a container, the
flex
values become the proportions of the space each takes. For example, if there are three views inside, and the first hasflex: 2
but the other two haveflex: 1
, the first will take half the container, and the other two will have a quarter each.
- Shorthand that combines
flexDirection
:- Sets primary axis
- Default is vertical alignment of items in container (makes most sense for typical portrait phone view; opposite to horizontal default in normal CSS flexbox)
- Can set
flexDirection
to similar values as w/ CSS, incl."row"
(left to right),"row-reverse"
(right to left), and"column-reverse"
(up from bottom).
justifyContent
:- Aligns along the primary (main) axis, same as w/ CSS - ex: horizontal if row
- Same values as w/ CSS (
"center"
,"flex-start"
,"flex-end"
,"space-around"
,"space-evenly"
,"space-between"
)
alignItems
:- Also functions how it does in CSS, aligning along the secondary access - ex: vertical if row
- Defaults to
"stretch"
- Same values as w/ CSS (
"center"
,"flex-start"
,"flex-end"
,"space-around"
,"space-evenly"
,"space-between"
) - Also can use
"baseline"
value; this means all the items have the same baseline (all the bottom edges will line up)
borderWidth
,borderColor
, andborderRadius
properties control thickness, color, and border radius- Can split out for specific sides (examples:
borderTopWidth
to thicken just the top border orborderTopLeftRadius
to round just the top left corner) - To make a circle, use a border radius half the size of the box
shadowColor
sets colorshadowOffset
takes object with width and height (shadowOffset: {width: 10, height: 10}
)shadowOpacity
takes a number between zero and one; 0===no shadow and 1===completely darkelevation
- Customisations only work on iOS (on Android, something either has a shadow or doesn't, and that's it, or you can change the elevation, but you can't change the color, etc.)
padding
,paddingLeft
,paddingTop
, etc. work like in CSS- Can also use
paddingHorizontal
andpaddingVertical
- Equivalent properties w/ margins as well