-
Notifications
You must be signed in to change notification settings - Fork 9
Things you need to know in our Frontend (a.k.a Farewell gift from Kyubin)
Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don’t replace your knowledge of React concepts. Instead, Hooks provide a more direct API to the React concepts you already know: props, state, context, refs, and lifecycle.
I recommend watching this youtube tutorials to learn the basics. If you prefer reading, the React official website has well-written documentation for Hooks.
Feeling lazy? start with useState & useEffect since these hooks are like bread and butter in our functional components.
Feeling lonely? there is a chat community called Reactiflux. Join them and be part of the community!
TypeScript has many benefits over vanilla JavaScript such as optional static typing, early spotted bugs, predictability, readability, rich IDE support, fast refactoring, and so on and so forth. Long live and prosper TypeScript! 🖖
Start learning all about TypeScript here. (I know this documentation is overwhelming but it's worth reading if you want to really learn the language.) Also, check out its Utility Types, some of them are being used in our application such as ReturnType<Type>
and Partial<Type>
.
The patterns and tools provided by Redux make it easier to understand when, where, why, and how the state in your application is being updated, and how your application logic will behave when those changes occur.
Not familiar with Redux? check out their official website here.
Redux Toolkit is suggested as best practice, simplifies most Redux tasks, prevents common mistakes, and makes it easier to write Redux applications.
This is the core library that we use in our application to basically handle all the Redux stuff such as creating reducers, actions, and selectors using their createSlice API. Also, note that our code structure is based on their advanced tutorial.
Want to know how we can mutate state in our reducers? (Normally you shouldn't and RTK just makes it seem like you can), learn more about how this works behind the scene.
React Router is the standard routing library for React. It has a simple API with powerful features like lazy code loading, dynamic route matching, and location transition handling built right in.
To learn more about the usage of this library including their declarative component API, check out their documentation here.
We are using React Router's useLocation
hook to detect URL query changes (ex. detecting station codes or time of interest changes in MoreCast) and we also use useHistory
to update the query in the URL. Use MoreCastPage.tsx
& WxDataForm.tsx
as a reference if you need to implement a similar feature.
Instead of downloading the entire app before users can use it, code splitting allows you to split your code into small chunks which you can then load on demand, which would reduce the initial load time.
Seeing having more individual products reside in one application, I think Code splitting should be introduced in the near future. It's actually pretty easy to achieve this since the project was bootstrapped with Create-React-App. Learn how to implement route-based code splitting with this link.
We are using keycloak-js to handle authentication through RedHat Single Sign-On. Check out web/src/features/auth/slices/authenticationSlice.ts
to see how the authentication flow works in our application.
We are using keycloak-js@9 as of writing but the Platform service team periodically updates the version so keep an eye on it because we need to update the Keycloak type definition (which is in web/src/types/keycloak.d.ts
) that I copy over from this package.
Need to update the type definition? Install the particular version of the package then find the type definition buried in node_modules
then copy and paste into our type definition.
We are fetching the keycloak-js with a script tag in web/public/index.html
. The script is coming from SSO hosted in our OpenShift platform where it uses a specific version of Keycloak, which is why we can't just install the package as a dependency in our project.
We are using Material-UI React library for component building blocks, which attempts to implement the technology agnostic, and similarly named Material Design. So whenever you create a new component, check out their built-in components to start with.
We are using their styling hook api called makeStyles to style our components. It has many benefits including theme nesting and dynamic styles based on props.
The following code snippet demonstrates how this hook can grab a theme color that's been initialized in web/src/app/App.tsx
and set properties based on props passed on through useStyles
in the component.
// web/src/components/ErrorMessage.tsx
const useStyles = makeStyles(theme => ({
root: {
color: theme.palette.error.main,
marginTop: (props: Props) => props.marginTop,
marginBottom: (props: Props) => props.marginBottom
}
}))
Use this trick if you need to modify certain properties in Material-UI components. Use this file as a reference web/src/features/fireWeather/components/WxDataForm.tsx
.
We test functions using Jest and business logic using Cypress. At least that's the idea. They run on one of our Github actions everytime when you create a PR or push more commits. Check out .github/workflows/integration.yml
to see what else is running in our Github actions.
The current coverage is based on solely Cypress tests. While we have pretty good coverage, this doesn't automatically mean all the business logic has been covered. For instance, when we test graphs we make sure there is a correct number of graphics displayed based on the fixture data. If I remove these checks Cypress will still think the graph components are covered because as long as graphs are displayed in one of our tests, it's been "covered". So I'd encourage you to write as many tests that are business logic related.
Initially, we started with d3.js for our graph library, however, we found that it has a steep learning curve and required someone with the knowledge to keep maintaining it. So we decided to switch to Plotly which is built on top of d3.js and easy to work with (relatively). While it provides great functionalities and convenience, there is a trade-off. Due to the nature of our graphs displaying lots of stuff and my belief on their React components not being optimized properly (maybe they are trying their best who knows), it slows down the browser when rendering these graphs. We can perhaps mitigate this issue by displaying only a handful of graphs initially and hide the rest and then let users open what they want to see.
Side note: I created a small example on how you can use React with d3.js properly. Use this as a reference if you ever need to go back to d3.
We display our graphs with Plotly's scatter traces. Use this documentation as a reference when you need to know more about all the <Plot />
component API.
We have a couple of React components that are built with OpenLayers library (check out web/src/features/map/VectorLayer.tsx
as an example). These components are based on this lovely Github repository. Get familiar with useContext hook before jumping into implementing a new OpenLayers component.