3' Ví dụ xây dựng MainLayout, Store đơn giản nhất (ok)

C:\Users\Administrator\Desktop\app\src\Routes\HomeRoutes.tsx

import React, {Component} from "react";
import { Switch, Route } from "react-router-dom";
import Home from "./../pages/Home";
import AuthenticatedGuard from './../guards/AuthenticatedGuard';
function HomeRoutes() {
	return (
		<Switch>
			<AuthenticatedGuard exact={true} path="/" component={Home} />
		</Switch>
	)
}
export default HomeRoutes;

C:\Users\Administrator\Desktop\app\src\guards\AuthenticatedGuard\index.tsx

import React, {Component} from "react";
import { connect } from 'react-redux'
import { Switch, Route, Redirect, RouteProps } from "react-router-dom";
interface AuthenProps {
	isAuthenticated: boolean
}
interface Props  extends AuthenProps, RouteProps {
}
interface StateProps {
	app: {
		isAuthenticated: boolean
	}
}
function AuthenticatedGuard(props: Props) {
	const {isAuthenticated, component = Component, ...rest } = props;
	return (
		<Route
			{...rest}
		  render={ (props) => {
		    	if(!isAuthenticated) {
		    		return <Redirect to="/login" />
		    	}
		    	return <Component {...props} />
		  	}
		  }
		/>
	)
}
const mapStateToProps = (state:StateProps) => {
	return {
		isAuthenticated: state.app.isAuthenticated
	}
}
const mapDispatchToProps = (dispatch:any) => {
	return {

	}
}
export default connect(mapStateToProps, mapDispatchToProps)(AuthenticatedGuard);

C:\Users\Administrator\Desktop\app\src\Store\index.tsx

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './../Reducer';
const composeEnhancers = typeof window === 'object' && process.env.NODE_ENV === 'development' && (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(applyMiddleware(thunk));
export const Store = createStore(rootReducer, enhancer);

C:\Users\Administrator\Desktop\app\src\index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Store } from './Store';
import { Provider } from 'react-redux';
ReactDOM.render(
  <React.StrictMode>
  	<Provider store={Store}>
    	<App />
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

C:\Users\Administrator\Desktop\app\src\Reducer\index.tsx

import { combineReducers } from 'redux';
import { AppReducer } from './app';
const rootReducer = combineReducers({
  app: AppReducer
})
export default rootReducer;

C:\Users\Administrator\Desktop\app\src\Reducer\app.tsx

import produce from 'immer';
const initialState = {
  isAuthenticated: false
}
export const AppReducer = (state = initialState, action:any) =>
produce(state, draft => {
  return state
})

C:\Users\Administrator\Desktop\app\src\Routes\LoginRoutes.tsx

import React from "react";
import { Switch, Route } from "react-router-dom";
import Login from "./../pages/Login";
function LoginRoutes() {
	return (
		<Switch>
			<Route exact path="/login" component={Login} />
		</Switch>
	)
}
export default LoginRoutes;

C:\Users\Administrator\Desktop\app\src\components\Header\index.tsx

import React from "react";
function Home() {
	return (
		<nav className="mb-1 navbar navbar-expand-lg bg-dark">
      <a className="navbar-brand animated swing infinite" href="#">Navbar</a>
      <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent-3" aria-controls="navbarSupportedContent-3" aria-expanded="false" aria-label="Toggle navigation">
        <span className="navbar-toggler-icon"></span>
      </button>
      <div className="collapse navbar-collapse" id="navbarSupportedContent-3">
        <ul className="navbar-nav mr-auto">
          <li className="nav-item active">
            <a className="nav-link waves-effect waves-light" href="#">Home
              <span className="sr-only">(current)</span>
            </a>
          </li>
          <li className="nav-item">
            <a className="nav-link waves-effect waves-light" href="#">Login</a>
          </li>
          <li className="nav-item">
            <a className="nav-link waves-effect waves-light" href="#">Product</a>
          </li>
        </ul>
      </div>
    </nav>
	)
}
export default Home;

C:\Users\Administrator\Desktop\app\src\templates\MainLayout.tsx

import React from 'react';
import Header from './../components/Header';
import Sidebar from './../components/Sidebar';
function MainLayout(props:any) {
	return (
		<div className="mainlayout">
			<Sidebar />
			<main className="main">
				<Header />
				{props.children}
			</main>
		</div>
	)
}
export default MainLayout;

C:\Users\Administrator\Desktop\app\src\index.css

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}
.mainlayout {
	display: flex;
	height: 100vh;
}
.sidebar {
	width: 250px;
  background-color: #000000;
}
.main {
	flex-grow: 1;
}

C:\Users\Administrator\Desktop\app\src\components\Sidebar\index.tsx

import React from "react";
function Sidebar() {
	return (
		<div className="sidebar">
			<h1 className="text-center text-white border-bottom pb-2">Sidebar</h1>
			<ul className="nav flex-column">
          <li className="nav-item">
            <a className="nav-link active" href="#">
              Home
            </a>
          </li>
          <li className="nav-item">
            <a className="nav-link" href="#">
              Login
            </a>
          </li>
          <li className="nav-item">
            <a className="nav-link" href="#">
              Product
            </a>
          </li>
        </ul>
		</div>
	)
}
export default Sidebar;

Last updated

Was this helpful?