added handlesubmit

parent 273f814f
This diff is collapsed.
......@@ -9,8 +9,11 @@
"preview": "vite preview"
},
"dependencies": {
"@reduxjs/toolkit": "^1.9.3",
"axios": "^1.3.4",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-redux": "^8.0.5"
},
"devDependencies": {
"@types/react": "^18.0.27",
......@@ -19,4 +22,4 @@
"typescript": "^4.9.3",
"vite": "^4.1.0"
}
}
\ No newline at end of file
}
import React from 'react';
import React, {useEffect, useState} from 'react';
import {getShortenLink, handleOriginalUrl} from './features/links/linkSlice';
import {useAppDispatch, useAppSelector} from './hooks';
import ILinkDTO from './types/ILinkDTO';
const App = () => {
return <div>App</div>;
const {shortUrl} = useAppSelector((state) => state.links.link);
const [linkState, setlinkState] = useState<string>('');
const dispatch = useAppDispatch();
const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
setlinkState(e.target.value);
dispatch(handleOriginalUrl(linkState));
};
const handleSubmit = (e: React.ChangeEvent<HTMLFormElement>) => {
e.preventDefault();
const link: ILinkDTO = {
originalUrl: linkState,
};
dispatch(getShortenLink(link));
};
useEffect(() => {}, [shortUrl]);
return (
<>
<form onSubmit={handleSubmit}>
<h1>Shorten your url</h1>
<input onChange={handleInput} type="text" />
<button type="submit">Shorten</button>
</form>
{shortUrl && (
<>
<h1>Your link now looks like this:</h1>
<a target="_blank" href={shortUrl}>
{shortUrl}
</a>
</>
)}
</>
);
};
export default App;
import {createAsyncThunk, createSlice, PayloadAction} from '@reduxjs/toolkit';
import ILink from '../../types/ILink';
import IState from '../../types/IState';
import axios from 'axios';
import ILinkDTO from '../../types/ILinkDTO';
const initialState: IState = {
link: {
originalUrl: '',
shortUrl: '',
} as ILink,
loading: false,
};
export const getShortenLink = createAsyncThunk(
'getShortenLink',
async (link: ILinkDTO) => {
try {
const response = await axios.post('http://localhost:3000/links', link);
return response.data;
} catch (err: unknown) {
const error = err as Error;
return error.message;
}
}
);
export const linkSlice = createSlice({
name: 'link',
initialState,
reducers: {
handleOriginalUrl: (state, action) => {
state.link = {...state.link, originalUrl: action.payload};
},
},
extraReducers: (builder) => {
builder
.addCase(getShortenLink.pending, (state, action) => {
state.loading = true;
})
.addCase(getShortenLink.rejected, (state, action) => {
state.loading = false;
})
.addCase(
getShortenLink.fulfilled,
(state, {payload}: PayloadAction<ILink>) => {
state.loading = false;
state.link.shortUrl = payload.shortUrl;
}
);
},
});
export default linkSlice.reducer;
export const {handleOriginalUrl} = linkSlice.actions;
import {TypedUseSelectorHook, useDispatch, useSelector} from 'react-redux';
import type {RootState, AppDispatch} from './store';
type DispatchFunc = () => AppDispatch;
export const useAppDispatch: DispatchFunc = useDispatch;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
import React from 'react';
import ReactDOM from 'react-dom/client';
import {Provider} from 'react-redux';
import App from './App';
import './index.css';
import {store} from './store';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<Provider store={store}>
<App />
</React.StrictMode>,
)
</Provider>
);
import {configureStore} from '@reduxjs/toolkit';
import linkSlice from './features/links/linkSlice';
export const store = configureStore({
reducer: {
links: linkSlice,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default interface ILink {
originalUrl: string;
shortUrl: string;
_id: string;
}
export default interface ILinkDTO {
originalUrl: string;
}
import ILink from './ILink';
export default interface IState {
link: ILink;
loading: boolean;
}
......@@ -9,7 +9,7 @@
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"module": "ES2022",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment