File tree Expand file tree Collapse file tree 10 files changed +140
-27
lines changed Expand file tree Collapse file tree 10 files changed +140
-27
lines changed Original file line number Diff line number Diff line change
1
+ import { useReducer } from "react" ;
1
2
import "./App.css" ;
2
3
import TodoForm from "./react-query/TodoForm" ;
3
4
import TodoList from "./react-query/TodoList" ;
5
+ import Counter from "./state-management/Counter" ;
6
+ import LoginStatus from "./state-management/LoginStatus" ;
7
+ import TaskList from "./state-management/TaskList" ;
8
+ import tasksReducer from "./state-management/reducers/tasksReducer" ;
9
+ import NavBar from "./state-management/NavBar" ;
10
+ import HomePage from "./state-management/HomePage" ;
11
+ import TasksContext from "./state-management/contexts/tasksContext" ;
12
+ import authReducer from "./state-management/reducers/authReducer" ;
13
+ import AuthContext from "./state-management/contexts/authContext" ;
4
14
5
15
6
16
function App ( ) {
17
+ const [ tasks , tasksDispatch ] = useReducer ( tasksReducer , [ ] ) ;
18
+ const [ user , authDispatch ] = useReducer ( authReducer , '' ) ;
19
+
7
20
return (
8
- < >
9
- < TodoForm />
10
- < TodoList />
11
- </ >
12
- )
21
+ < AuthContext . Provider value = { { user, dispatch : authDispatch } } >
22
+ < TasksContext . Provider value = { { tasks, dispatch : tasksDispatch } } >
23
+ < NavBar />
24
+ < HomePage />
25
+ </ TasksContext . Provider >
26
+ </ AuthContext . Provider >
27
+ ) ;
13
28
}
14
29
15
30
export default App ;
Original file line number Diff line number Diff line change 1
- import { useState } from 'react' ;
1
+ import { useReducer , useState } from 'react' ;
2
+ import counterReducer from './reducers/counterReducer' ;
2
3
3
4
const Counter = ( ) => {
4
- const [ value , setValue ] = useState ( 0 ) ;
5
+
6
+ const [ value , dispatch ] = useReducer ( counterReducer , 0 ) ;
5
7
6
8
return (
7
9
< div >
8
10
Counter ({ value } )
9
11
< button
10
- onClick = { ( ) => setValue ( value + 1 ) }
12
+ onClick = { ( ) => dispatch ( { type : 'INCREMENT' } ) }
11
13
className = "btn btn-primary mx-1"
12
14
>
13
15
Increment
14
16
</ button >
15
17
< button
16
- onClick = { ( ) => setValue ( 0 ) }
18
+ onClick = { ( ) => dispatch ( { type : 'RESET' } ) }
17
19
className = "btn btn-primary mx-1"
18
20
>
19
21
Reset
Original file line number Diff line number Diff line change 1
- import { useState } from "react" ;
1
+ import { useContext , useReducer , useState } from "react" ;
2
+ import authReducer from "./reducers/authReducer" ;
3
+ import AuthContext from "./contexts/authContext" ;
2
4
3
5
const LoginStatus = ( ) => {
4
- const [ user , setUser ] = useState ( '' ) ;
6
+ const { user, dispatch } = useContext ( AuthContext ) ;
5
7
6
8
if ( user )
7
9
return (
8
10
< >
9
11
< div >
10
12
< span className = "mx-2" > { user } </ span >
11
- < a onClick = { ( ) => setUser ( '' ) } href = "#" >
13
+ < a onClick = { ( ) => dispatch ( { type : 'LOGOUT' } ) } href = "#" >
12
14
Logout
13
15
</ a >
14
16
</ div >
15
17
</ >
16
18
) ;
17
19
return (
18
20
< div >
19
- < a onClick = { ( ) => setUser ( 'mosh.hamedani' ) } href = "#" >
21
+ < a onClick = { ( ) => dispatch ( { type : 'LOGIN' , username : 'raf.avetisov' } ) } href = "#" >
20
22
Login
21
23
</ a >
22
24
</ div >
Original file line number Diff line number Diff line change
1
+ import { useContext } from 'react' ;
1
2
import LoginStatus from './LoginStatus' ;
3
+ import TasksContext from './contexts/tasksContext' ;
2
4
3
5
const NavBar = ( ) => {
6
+
7
+ const { tasks} = useContext ( TasksContext ) ;
8
+
4
9
return (
5
10
< nav className = "navbar d-flex justify-content-between" >
6
- < span className = "badge text-bg-secondary" > 4 </ span >
11
+ < span className = "badge text-bg-secondary" > { tasks . length } </ span >
7
12
< LoginStatus />
8
13
</ nav >
9
14
) ;
Original file line number Diff line number Diff line change 1
- import { useState } from 'react' ;
2
-
3
- interface Task {
4
- id : number ;
5
- title : string ;
6
- }
1
+ import { useContext , useReducer , useState } from 'react' ;
2
+ import tasksReducer from './reducers/tasksReducer' ;
3
+ import TasksContext from './contexts/tasksContext' ;
4
+ import AuthContext from './contexts/authContext' ;
7
5
8
6
const TaskList = ( ) => {
9
- const [ tasks , setTasks ] = useState < Task [ ] > ( [ ] ) ;
10
-
7
+ const { tasks, dispatch } = useContext ( TasksContext ) ;
8
+ const { user } = useContext ( AuthContext ) ;
11
9
return (
12
10
< >
11
+ < p > User: { user } </ p >
13
12
< button
14
13
onClick = { ( ) =>
15
- setTasks ( [
16
- { id : Date . now ( ) , title : 'Task ' + Date . now ( ) } ,
17
- ...tasks ,
18
- ] )
14
+ dispatch ( {
15
+ type : 'ADD' ,
16
+ task : {
17
+ id : Date . now ( ) ,
18
+ title : 'Task ' + Date . now ( )
19
+ }
20
+ } )
19
21
}
22
+
20
23
className = "btn btn-primary my-3"
21
24
>
22
25
Add Task
@@ -31,7 +34,10 @@ const TaskList = () => {
31
34
< button
32
35
className = "btn btn-outline-danger"
33
36
onClick = { ( ) =>
34
- setTasks ( tasks . filter ( ( t ) => t . id !== task . id ) )
37
+ dispatch ( {
38
+ type : 'DELETE' ,
39
+ taskId : task . id
40
+ } )
35
41
}
36
42
>
37
43
Delete
Original file line number Diff line number Diff line change
1
+ import { Dispatch } from "react" ;
2
+ import { AuthAction } from "../reducers/authReducer" ;
3
+ import React from "react" ;
4
+
5
+ interface AuthContextType {
6
+ user : string ;
7
+ dispatch : Dispatch < AuthAction > ;
8
+ }
9
+
10
+ const AuthContext = React . createContext < AuthContextType > ( { } as AuthContextType ) ;
11
+
12
+ export default AuthContext ;
Original file line number Diff line number Diff line change
1
+ import { Dispatch } from "react" ;
2
+ import { Task , TaskAction } from "../reducers/tasksReducer" ;
3
+ import React from "react" ;
4
+
5
+ interface TasksContextType {
6
+ tasks : Task [ ] ;
7
+ dispatch : Dispatch < TaskAction > ;
8
+ }
9
+
10
+ const TasksContext = React . createContext < TasksContextType > ( { } as TasksContextType ) ;
11
+
12
+ export default TasksContext ;
Original file line number Diff line number Diff line change
1
+
2
+ interface LoginAction {
3
+ type : 'LOGIN' ;
4
+ username : string ;
5
+ }
6
+
7
+ interface LogoutAction {
8
+ type : 'LOGOUT' ;
9
+ }
10
+
11
+ export type AuthAction = LoginAction | LogoutAction ;
12
+
13
+ const authReducer = ( state : string , action : AuthAction ) : string => {
14
+ if ( action . type === 'LOGIN' ) return action . username ;
15
+ if ( action . type === 'LOGOUT' ) return '' ;
16
+ return state ;
17
+ }
18
+
19
+ export default authReducer ;
Original file line number Diff line number Diff line change
1
+
2
+ interface Action {
3
+ type : 'INCREMENT' | 'RESET' ;
4
+ }
5
+
6
+ const counterReducer = ( state : number , action : Action ) => {
7
+ if ( action . type === 'INCREMENT' ) return state + 1 ;
8
+ if ( action . type === 'RESET' ) return 0 ;
9
+ return state ;
10
+ }
11
+
12
+ export default counterReducer ;
Original file line number Diff line number Diff line change
1
+
2
+ export interface Task {
3
+ id : number ;
4
+ title : string ;
5
+ }
6
+
7
+ interface AddTask {
8
+ type : 'ADD' ;
9
+ task : Task ;
10
+ }
11
+
12
+ interface DeleteTask {
13
+ type : 'DELETE' ;
14
+ taskId : number ;
15
+ }
16
+
17
+ export type TaskAction = AddTask | DeleteTask ;
18
+
19
+ const tasksReducer = ( tasks : Task [ ] , action : TaskAction ) : Task [ ] => {
20
+ switch ( action . type ) {
21
+ case 'ADD' :
22
+ return [ action . task , ...tasks ] ;
23
+ case 'DELETE' :
24
+ return tasks . filter ( t => t . id !== action . taskId ) ;
25
+ }
26
+ }
27
+
28
+ export default tasksReducer ;
You can’t perform that action at this time.
0 commit comments