Notes
Notes to prepare for a Technical Interview for a Software Engineer role at Mobal.io
Introduction
The technical interview is a live coding interview where you are coding the frontend of an app. You have to connect the frontend to a backend server which you can access through an api. You can choose any modern frontend framework that want to complete the task.
Technologies
- React.js
Reproduction
Clone the repository
Ensure you have npm
installed
$ npm -v
Go to repository directory
$ cd mobal
Install packages
$ npm install
Launch
$ npm start
Creation
Create React app.
Prerequsites: Node >= 14.0.0
and npm >= 5.6
$ npx create-react-app mobal
$ cd mobal
Launch
$ npm start
What? Some interesting readings
- https://www.freecodecamp.org/news/learn-react-by-building-a-weather-app/
- https://www.simplilearn.com/tutorials/reactjs-tutorial
- https://github.com/raulterhesdev/redux-toolkit-introduction-youtube
Organization and Standards
Notables
-
--save-dev
(only used in the development, not in production) -
--save
(production dependencies) -
--global
or-g
(used globally i.e can be used anywhere in our local system)
Cnvert strings to paths
- Either use
const regex = /[^a-zA-Z0-9]+/g;
const title = "hello123!@#";
// Convert
const path = title.trim().replace(regex, "-").toLowerCase();
Structure
-- src
-- api
-- components
-- styles
-- pages
-- utilities
Lints
Install prettier as a Dev dependency
$ npm install prettier --save-dev
Create a .prettierrc
at root and
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": false
}
UI and Styling
Install Material-UI: https://mui.com/material-ui/getting-started/installation/
$ npm install @mui/material @emotion/react @emotion/styled
$ npm install @mui/icons-material
Moment.js to format our time
$ npm install moment
API and Fetch Requests
Axios
$ npm install axios
Update multiple items
Reference: https://stackoverflow.com/a/32101994/8050183
// PATCH /items
const params = [ { id: 1, name: 'foo' }, { id: 2, name: 'bar' } ]
// Post data to api
async function postResource(path, params, handleResponse) {
const url = API_URL + path;
// Only send request if there's a authorize cookie set
// if (!token) return;
// headers
const headers = {
headers: {
"Content-Type": "application/json",
Authorization: "token",
},
};
await axios
.post(url, params, headers)
.then((response) => {
handleResponse({ resource: response.data });
})
.catch((error) => {
handleResponse({ resource: null, message: error.message });
console.log("POST Resource Error");
console.log(error);
});
}
Global store
$ npm install @reduxjs/toolkit
$ npm install react-redux
How to create a store
createSlice
- Create a directory to keep everything,
store
- Create a file to handle the update and reading of a specific global variable. Lets call it a
slice.js
- Initialize the object
createSlice({})
with values:-
name
: A unique string within the global stores -
initialState: {}
: The default, initial state of the global variable. The keys in this object will be updated in thereducers
-
reducers: {}
: Here we declare - You can use switch statements when having multiple variables
-
// currentUserSlice.js
import { createSlice } from "@reduxjs/toolkit";
export const currentUserSlice = createSlice({
name: "currentUser",
initialState: {
user: null,
},
reducers: {
updateCurrentUser: (state, action) => {
state.user = action.payload;
},
},
});
// Action creators are generated for each case reducer function
export const { updateCurrentUser } = currentUserSlice.actions;
export default currentUserSlice.reducer;
Import all the store slices within the global store
import { configureStore } from "@reduxjs/toolkit";
// reducer import
import currentUserReducer from "./currentUserSlice";
const store = configureStore({
reducer: {
currentUser: currentUserReducer,
},
});
export default store;
Then, read and update persisted store value where ever
// Read
import { useDispatch, useSelector } from "react-redux";
const Component = function Component() {
const dispatch = useDispatch();
// Update
dispatch(updateCurrentUser({ name: "Axel", foo: true }));
// Read value
const currentUser = useSelector((state) => state.currentUser.user);
return null;
};
export default Component;
createReducer
- Create a directory to keep everything,
store
- Create
actions
directory to keep all defined action names for specificreducers
-
createAction
contains action name which will be used to dispatch payload
-
// /actions/counterActions.js
import { createAction } from "@reduxjs/toolkit";
export const increment = createAction("counter/increment");
- Create a
reducer
directory to handle the update and reading of a specific global variables. Lets call it aresourceReducer.js
- Create
initialState: {}
for variable/state - import
createReducer({})
and set:-
initialState
argumenet -
builder
: A callback object which provides addCase, addMatcher and addDefaultCase functions that may be called to define what actions this reducer will handle.
-
// /reducers/counterReducer.js
const counterReducer = createReducer(initialState, (builder) => {
builder.addCase(increment, (state, action) => {
state.value++;
});
});
Create store
// store.js
import { configureStore } from "@reduxjs/toolkit";
import booksReducer from "./reducers/booksReducer";
const store = configureStore({
reducer: { books: booksReducer },
});
export default store;
Then, read and update persisted store value where ever
// Read
import { useDispatch, useSelector } from "react-redux";
import { deleteBook } from "../../store/actions/booksActions";
const Component = function Component() {
const dispatch = useDispatch();
// Update
dispatch(deleteBook(id));
// Read value
const books = useSelector((state) => state.books.books);
return null;
};
export default Component;
For both ways, initialize store at top level component
// Top level component, e.g App.js
import { Provider } from "react-redux";
import store from "../store/store";
const App = function App() {
<Provider store={store}>
{ children }
<Provider>
}
export default App;
Routing
$ npm install react-router-dom
Routes structure
<!-- At top level -->
<BrowserRouter>
<div />
</BrowserRouter>
then
<Routes>
<Route path="/" element={<Dashboard />}>
<Route path="tasks" element={<DashboardTasks />} />
</Route>
</Routes>
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.