Created
August 13, 2023 08:51
-
-
Save thenaveensaggam/1cc959aeb768cbc51004c12b27bebe6e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
React with TypeScript | |
--------------------- | |
-> npx create-react-app first-app --template typescript | |
-> npm i bootstrap@5.3.0-alpha2 | |
-> npm i bootstrap-icons | |
-> npm i @types/bootstrap | |
Context API (useContext()) | |
----------- | |
-> create a context | |
export const ProductContext = React.createContext({} as IProduct); | |
-> provide the context | |
<ProductContext.Provider value={product}> | |
<ComponentOne/> | |
</ProductContext.Provider> | |
-> consume the context | |
const product = useContext(ProductContext); | |
<pre>{JSON.stringify(product)}</pre> | |
-> useEffect() | |
------------------------------------------ | |
-> side effects , API calls, Services call | |
-> lifeCycle Hook | |
/** | |
componentDidMount() | |
executes only once when the page is fully loaded / rendered on DOM | |
*/ | |
useEffect(() => { | |
// statements | |
}, []); | |
/** | |
componentDidUpdate() | |
everytime when there is a change in the dependency | |
*/ | |
useEffect(() => { | |
// statements | |
}, [productId]); | |
/** | |
componentDidUnMount() | |
executes only once, when the component is removed from the DOM | |
*/ | |
useEffect(() => { | |
return () => { | |
// statements | |
} | |
}, []); | |
Connect React JS to server | |
-------------------------- | |
-> install axios from npm | |
-> npm install axios @types/axios | |
-> use axios for get data from server | |
-> axios.get(serverUrl); | |
-> axios.post(serverUrl); | |
-> axios.put(serverUrl); | |
-> axios.delete(serverUrl); | |
-> Example | |
private static serverUrl: string = "https://jsonplaceholder.typicode.com"; | |
public static getAllUsers(): Promise<{ data: IUser[] }> { | |
return axios.get(`${this.serverUrl}/users`); | |
} | |
inside component | |
-------------------- | |
useEffect(() => { | |
UserService.getAllUsers().then((response) => { | |
setUsers(response.data); | |
}).catch((error) => { | |
console.error(error); | |
}); | |
}, []); | |
React JS Routing | |
---------------- | |
Wep Application -> modules -> web pages -> components | |
reception | |
billing | |
doctors | |
medical-records | |
http://localhost:3000/ -> Home | |
http://localhost:3000/users/login -> Login Page | |
http://localhost:3000/users/register -> Registration Page | |
http://localhost:3000/users/profile -> Profile Page | |
http://localhost:3000/customers/all -> All the customers | |
http://localhost:3000/customers/:customerId -> the customer data | |
http://localhost:3000/customers/:customerId -> the customer data | |
-> url params | |
https://www.google.co.in/?gws_rd=ssl -> url queries | |
https://www.google.co.in/search?q=javascript&device=hp&location=hyd | |
install react-router-dom | |
------------------------ | |
npm install react-router-dom @types/react-router-dom | |
Important Hooks for routing | |
--------------- | |
const location = useLocation(); // for path object | |
const urlParams = useParams(); // for url params | |
let [searchParams, setSearchParams] = useSearchParams(); // for url queries | |
const navigate = useNavigate(); // for programmatic navigation | |
Contact Manager Application | |
----------------------------- | |
Contact Manager with JavaScript | |
------------------------------- | |
-> Server Setup | |
---------------- | |
-> install node js -> node --version -> 18.x | |
-> create a folder "server" | |
-> create a package.json file -> npm init --yes | |
-> "npm install json-server" | |
-> place the "db.json" in server folder | |
-> update package.json start script | |
"start" : "json-server --watch db.json --port 9000" | |
-> start the server "npm start" | |
NOTE : To test the application in your local system, enter the below 2 commands inside "server" folder | |
-> npm install | |
-> npm start | |
-> Test the Server (using postman rest client / insomnia rest client) | |
------------------ | |
GET -> to get data from server -> READ | |
POST -> to create data at server -> CREATE | |
PUT -> to update data at server -> UPDATE | |
DELETE -> to delete data at server -> DELETE | |
/** | |
@usage : to get all contacts | |
@method : GET | |
@body : no-params | |
@url : http://localhost:9000/contacts | |
*/ | |
/** | |
@usage : get a contact | |
@method : GET | |
@body : no-params | |
@url : http://localhost:9000/contacts/:contactId | |
*/ | |
/** | |
@usage : create a contact | |
@method : POST | |
@body : name, imageUrl, email, mobile, company, title, groupId | |
@url : http://localhost:9000/contacts/ | |
*/ | |
/** | |
@usage : Update a contact | |
@method : PUT | |
@body : name, imageUrl, email, mobile, company, title, groupId | |
@url : http://localhost:9000/contacts/:contactId | |
*/ | |
/** | |
@usage : Delete a contact | |
@method : DELETE | |
@body : no-params | |
@url : http://localhost:9000/contacts/:contactId | |
*/ | |
/** | |
@usage : Get all groups | |
@method : GET | |
@body : no-params | |
@url : http://localhost:9000/groups/ | |
*/ | |
/** | |
@usage : Get a group | |
@method : GET | |
@body : no-params | |
@url : http://localhost:9000/groups/:groupId | |
*/ | |
-------------------------------------------- | |
Redux Toolkit installation | |
-------------------------------------------- | |
npm install @reduxjs/toolkit react-redux redux-logger redux-thunk | |
npm install @types/react-redux @types/redux-logger @types/redux-thunk | |
---------------------------------------------------------- | |
Redux Toolkit Configuration | |
---------------------------------------------------------- | |
store.js | |
--------- | |
import {configureStore, Store} from "@reduxjs/toolkit"; | |
import rootReducer from "./rootReducer"; | |
import {useDispatch} from "react-redux"; | |
import logger from "redux-logger"; | |
import thunk from 'redux-thunk'; | |
const store: Store = configureStore({ | |
reducer: rootReducer, | |
middleware: [logger, thunk] | |
}) | |
export default store; | |
export type RootState = ReturnType<typeof store.getState> | |
export type AppDispatch = typeof store.dispatch; | |
export const useAppDispatch = () => useDispatch<AppDispatch>() | |
Root Reducer | |
------------ | |
import {combineReducers} from "@reduxjs/toolkit"; | |
import * as counterReducer from "./counter/counterSlice"; | |
import * as employeeReducer from './employees/employeeSlice'; | |
import * as userReducer from './user-list/userSlice'; | |
const rootReducer: any = combineReducers({ | |
[counterReducer.counterFeatureKey]: counterReducer.counterSlice.reducer, | |
[employeeReducer.employeeFeatureKey]: employeeReducer.employeeSlice.reducer, | |
[userReducer.usersFeatureKey]: userReducer.userSlice.reducer | |
}); | |
export default rootReducer; | |
index.tsx | |
---------- | |
import {Provider} from "react-redux"; | |
import store from "./redux/store"; | |
root.render( | |
<React.StrictMode> | |
<Provider store={store}> | |
<App/> | |
</Provider> | |
</React.StrictMode> | |
); | |
Counter Slice | |
--------------- | |
import {createSlice} from "@reduxjs/toolkit"; | |
export const counterFeatureKey = "counterFeature"; | |
export interface InitialState { | |
count: number; | |
} | |
const initialState: InitialState = { | |
count: 0 | |
} | |
export const counterSlice = createSlice({ | |
name: "counter", | |
initialState: initialState, | |
reducers: { | |
incrementCounter: (state, action) => { | |
state.count = state.count + 1; | |
}, | |
decrementCounter: (state, action) => { | |
state.count = state.count - 1; | |
}, | |
incrementCounterBy: (state, action) => { | |
let {value} = action.payload; | |
state.count = state.count + value; | |
} | |
} | |
}); | |
export const {incrementCounter, decrementCounter, incrementCounterBy} = counterSlice.actions; | |
Counter Component | |
------------------ | |
const dispatch: AppDispatch = useDispatch(); | |
// get data from the redux store | |
const counterState: counterReducer.InitialState = useSelector((store: RootState) => { | |
return store[counterFeatureKey]; | |
}) | |
let clickIncr = (): void => { | |
dispatch({ | |
type: `${counterReducer.incrementCounter}` | |
}) | |
}; | |
let clickIncrBy = (value: number): void => { | |
dispatch({ | |
type: `${counterReducer.incrementCounterBy}`, | |
payload: {value: value} | |
}) | |
}; | |
User Actions | |
------------ | |
import {createAsyncThunk} from "@reduxjs/toolkit"; | |
import {ProductRequestView} from "../../modules/products/models/ProductRequestView"; | |
import {ProductResponseView} from "../../modules/products/models/ProductResponseView"; | |
import {ProductService} from "../../modules/products/services/ProductService"; | |
import {AuthUtil} from "../../util/AuthUtil"; | |
export const createProductAction: any = createAsyncThunk('products/createProductAction', | |
async (product: ProductRequestView, {rejectWithValue}): Promise<{ msg: string; product: ProductResponseView } | any> => { | |
try { | |
if (AuthUtil.setTokenToRequestHeader()) { // always set this for private urls | |
let response = await ProductService.createProduct(product); | |
return response.data; | |
} | |
} catch (err: any) { | |
if (!err.response) { | |
throw err | |
} | |
return rejectWithValue(err.response.data) | |
} | |
}) | |
User Slice | |
----------- | |
import {createSlice, isRejectedWithValue, SerializedError} from "@reduxjs/toolkit"; | |
import {ProductResponseView} from "../../modules/products/models/ProductResponseView"; | |
import * as productActions from "./product.actions"; | |
import {ToastUtil} from "../../util/ToastUtil"; | |
export const productFeatureKey = "productFeature"; | |
export interface InitialState { | |
loading: boolean; | |
errorMessage: SerializedError; | |
products: ProductResponseView[]; | |
product: ProductResponseView; | |
} | |
const initialState: InitialState = { | |
loading: false, | |
errorMessage: {} as SerializedError, | |
products: [] as ProductResponseView[], | |
product: {} as ProductResponseView | |
}; | |
export const productSlice = createSlice({ | |
name: 'productSlice', | |
initialState: initialState, | |
reducers: {}, | |
extraReducers: (builder) => { | |
// createProductAction | |
builder.addCase(productActions.createProductAction.pending, (state) => { | |
state.loading = true; | |
}).addCase(productActions.createProductAction.fulfilled, (state, action) => { | |
state.loading = false; | |
ToastUtil.displaySuccessToast(action.payload.msg); | |
}).addCase(productActions.createProductAction.rejected, (state, action) => { | |
state.loading = false; | |
if (isRejectedWithValue(action)) { | |
ToastUtil.displayErrorToast(action.payload.msg); | |
} | |
}) | |
User List Component | |
-------------------- | |
const dispatch: AppDispatch = useAppDispatch(); | |
// get data from redux store | |
const userState: userReducer.InitialState = useSelector((store: RootState) => { | |
return store[usersFeatureKey]; | |
}); | |
let {loading, users, errorMessage} = userState; | |
useEffect(() => { | |
dispatch(userActions.getAllUsersFromServer()) | |
}, []); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment