Skip to main content

· 2 min read
Marcus Koh

Problem

You are tasked to create a full-page bottom-sheet like experience to display some content within your React Native app. You wanted to use @gorhom/bottom-sheet for this use case, however there are some bugs and you need to swap @gorhom/bottom-sheet out for other libraries or find other techniques to achieve the same UI.

Today, we will explore how you can use react-navigation to achieve similar experience.

Solution

To achieve what we want of a full-page bottom-sheet, you can use react-navigation with some params configured such that the page itself becomes a modal.

This will be crucial to the user experience because it provides the user with the ability to swipe to dismiss the page.

Apart from being a modal, you also need to provide some form of "darkened" background that is translucent, so that it indicates to the user it is a "bottom-sheet". That is where the cardOverlay: Overlay comes into play. We will provide a component that is this "darkened" view.

Here is a snippet of how you should configure your Screen:

<Stack.Screen
name="Modal"
component={ModalScreen}
options={{
...TransitionPresets.ModalSlideFromBottomIOS, // provides bottom-up animation when launching page.
presentation: 'transparentModal',
cardOverlayEnabled: true,
headerTitleAlign: 'center',
headerShown: false,
cardOverlay: Overlay,
}}
/>

To let the user see the Overlay background, you have to have a transparent view within your page. Since we are doing a full-page bottom-sheet, we need set the height of this transparent view to be the safe area height.

Here is a snippet of the modal page:

const ModalScreen = () => {
const navigation = useNavigation<any>();

const onClose = () => {
navigation.canGoBack() && navigation.navigate('Home');
};
const top = useSafeAreaInsets().top;
return (
<View style={styles.root}>
<View style={[{ height: top }, styles.emptyContainer]} />
<View style={styles.contentContainer}>
<View style={styles.modalHeaderContainer}>
<Button title="close" onPress={onClose} />
<Text>Hello World</Text>
<Button title="save"></Button>
</View>
<Text>Hello</Text>
</View>
</View>
);
};

Here is how the full-page bottom-sheet looks like:

Reference:

· One min read
Marcus Koh

Problem

Recently, I faced a dilemma when naming my react functions. I saw my colleagues named some functions as

onClickDate
onClickStartTime
onClickxxxx

To me previously, this was not acceptable because, I was thinking that when the user performed a certain action, then we trigger the function. So I would name it as

onDateClicked
onStartTimeClicked
onXXXClicked

However, when I surveyed around with other senior engineers and did some googling, I realised that my idea of "correct" function names has been wrong all these while. There should not be any past tense in your function names!

Solution

Naming your functions in present tense. For eg:

onSelectDate
onSelectXXX

onSubmit
onConfirm

onChangeXXXX
onPressXXXX

handleChangeXXX
handlePressXXX
handleSelectXXX

To me code quality is very important which translate to naming your functions clearly. Moving forward, I shall stick to naming them with present tense for action related functions.

Reference:

· 2 min read
Marcus Koh

Problem

There are times where you want to create your own custom hooks to be shared within your teammates or across projects. Usually there are 2 ways to write your custom hook. You either return an object or a tuple.

  1. Returning as an object
const useFirstName = () => {
const [firstName, setFirstName] = useState("");

return {
firstName,
setFirstName
}
}

Considering if you are returning as an object, you do not need to type it already because the object is inferred.

  1. Returning as an array
const useFirstName = () => {
const [firstName, setFirstName] = useState("");

return [firstName,setFirstName]
}

There will be some typescript issue with this because the array now becomes type of const useFirstName: () => (string | React.Dispatch<React.SetStateAction<string>>)[] .

So when you attempt to use the hook, you will realise that the type is string | React.Dispatch<React.SetStateAction<string>>, which isn't what you want.

Solution

as const to the rescue again!

const useFirstName = () => {
const [firstName, setFirstName] = useState("");

return [firstName,setFirstName] as const
}

This will return the correct type for your useFirstName where specifically item 0 (your firstName) is of type string and item 1 will be your setter function.

· 3 min read
Marcus Koh

I personally have not used enums much in my professional experience because I find them difficult to understand and I can't clearly visualise their data structure during development of mobile apps.

Recently, I have stumbled upon this particular youtube video that has piqued my interest in understanding enums vs as consts in Typescript.

· 6 min read
Marcus Koh

Requirements

You are tasked to setup multiple repositories for a React Native project. Each repository essential serve as a business function, eg: User Login, User Address, Checkout, etc... Each business team should be able to work in an isolated manner and not be affected by another team.

Research

Based on the given requirements, it essentially describes a mutli-repo approach to building react-native applications. This multi-repo approach is not uncommon in the industry and is frequently used to split business functions into individual teams. However, when you try to google multi-repo react-native there are barely any results that is suitable. Most of the industry today have shifted to using mono-repo because of its convient and easy to develop style.

There are many tools that are designed for mono-repo that can also be used for multi-repo because they are essentially about the same. Just how you place the folders and the node_modules.