Solve some potholes that novice construction projects may encounter.

Create your new project

As recommended by the official website

$NPX create-react-app my-app --typescript $# or $yarn create react-app my-app --typescriptCopy the code

The directory structure is as follows:

                             

Introduce sass (or less depending on your usage habits)

$ npm install node-sass --save
$ # or
$ yarn add node-sassCopy the code

After successful installation

You can change the app. CSS file to app. SCSS and discover that the file takes effect. When we want the style not to work globally,

Need to modify the codeWill the import'./App.scss'; Change to import styles from'./App.scss';Copy the code

When we find that none of the styles are in effect, we hit our first pothole. Looking at the Webpack configuration, we find:



The scssModule module detects that name.module. SCSS files are modularized.

If you want all. SCSS files can be modular introduction, can be regular matching. Module removed, as follows:

Execute YARN eject to expose all configuration filesCopy the code

Modify the config/webpack.config.js file to

const sassModuleRegex = /\.module\.(scss|sass)$/;
# modified to
const sassModuleRegex = /\.(scss|sass)$/;Copy the code

Configure antD loading on demand

# add dependency ANTD
yarn add antd
# installed Babel - plugin - import
yarn add babel-plugin-importCopy the code

To add a configuration file, add the. Babelrc file in the outermost directory of the project and add the following configuration:

{    
    "presets": ["react-app"]."plugins": [["import", {          
                    "libraryName": "antd"."libraryDirectory": "es"."style": "css"}}]]Copy the code

Add the routing

Install react-router-dom
yarn add react-router-domCopy the code

Add a route folder and create an index. TSX file under that folder. We can create two pages: Index and Welcome

The contents of index.tsx are as follows:

import React from 'react';
import { HashRouter, Route, Switch } from 'react-router-dom';
import Home from '.. /pages/Home';
import Welcome from '.. /pages/Welcome';

export default () => {    
    return (        
            <HashRouter>            
                <Switch>                
                    <Route exact path="/" component={Home} />                
                    <Route exact path="/index" component={Home} />                
                    <Route exact path="/welcome" component={Welcome} />            
                </Switch>        
            </HashRouter>    
    )
}Copy the code

Add the status management tool Concent

Concent is a predictable, zero-intrusion, high-performance, enhanced state management tool that combines the advantages of vuex, Redux, Mobx and many other front-end data warehousing tools.

# install dependencies
yarn add concent Copy the code

We’re going to use this tool to expand and shrink the sidebar menu when we click a button;

Create the runconcent. ts file in the outermost layer with the following contents:

import { run } from 'concent';
run({
  "$$global":{
     state:{ collapsed: false},
     reducer:{
        changeCollapse(_: any,moduleState:{collapsed:boolean}){         
            const {collapsed} = moduleState;         
            return{ collapsed: ! collapsed } } } } })TSX import './runConcent';Copy the code

Add the Layout component to realize the overall layout

The overall file structure is as follows:

            

BasicHeader components:

import React from 'react';
import { Icon } from 'antd';
import { registerHookComp } from 'concent';
import styles from './index.scss';

type TypeDescriptor = {    type: string, module? : string, reducerModule? : string, };type ICtxBase = {    
    dispatch(        
        type: string | TypeDescriptor, payload? :any, renderKey? :string, delay? :number, ): Promise<object | undefined>} const setup = (ctx:ICtxBase):{[key: string]:any} => {return {        
            changeCollapse: () =>{            
                ctx.dispatch('changeCollapse')}}}export default registerHookComp({    
            module: "$$global",    
            setup,    
            render: (ctx:any) =>{        
                return (           
                         <>                
                            <Icon  className={styles.trigger} type={ctx.state.collapsed ? 'menu-unfold' : 'menu-fold'}  onClick={ctx.settings.changeCollapse}  />            
                         </>        
                        )    
                    }
            });Copy the code

BasicMenu components:

import React, { memo } from 'react';
import { Menu, Icon } from 'antd';
import { HashRouter, Link, useLocation } from 'react-router-dom';
import { useConcent,ICtxBase } from 'concent';

const setup = (ctx:ICtxBase)=>{    
        return {        
                getSelectedKeys(pathname:string){           
                     return pathname        
                }    
    }}

export default memo(() => {    
        const { settings } = useConcent({ setup })    
        return (        
                    <HashRouter>            
                        <Menu theme="dark" mode="inline" selectedKeys={settings.getSelectedKeys(useLocation().pathname)}>                
                            <Menu.Item key="/index">                    
                                <Link to="/index"> 
                                    <Icon type="user" />                        
                                    <span>index</span>                    
                                </Link>                
                            </Menu.Item>                
                            <Menu.Item key="/welcome">                    
                                <Link to="/welcome">                        
                                    <Icon type="video-camera" />                        
                                    <span>welcome</span>                    
                                </Link>                
                            </Menu.Item>                
                            <Menu.Item key="3">                    
                                <Icon type="upload" />                    
                                <span>nav 3</span>                
                            </Menu.Item>            
                         </Menu>        
                        </HashRouter>    
                    )
})Copy the code

The index. The TSX composite structure:

import React from 'react';
import { Layout } from 'antd';
import BasicMenu from './BasicMenu';
import BasicHeader from './BasicHeader';
import styles from './index.scss';
import { useConcent } from 'concent';
import { HashRouter } from 'react-router-dom';

const { Header, Sider, Content } = Layout;

export default functionBasicLayout(props: { children? : React.ReactChild }): JSX.Element { const { state } = useConcent({ module:"$$global"}); // Use HashRouter to wrap BasicMenu components. UseLocation methods can only be used inside componentsreturn (    
                <Layout className={styles.myLayout}>      
                    <Sider trigger={null} collapsible collapsed={state.collapsed}>
                        <div className={styles.logo} />        
                        <HashRouter><BasicMenu /></HashRouter>      
                    </Sider>      
                    <Layout>        
                        <Header style={{ background: '#fff', padding: 0, textAlign: "left" }}>          
                            <BasicHeader />        
                        </Header>        
                        <Content style={{ margin: '24px 16px',  padding: 24,  background: '#fff',  minHeight: 280, }}> 
                            {props.children}        
                        </Content>      
                    </Layout>    
                </Layout>  
    )
}Copy the code

The overall effect is as follows:



The project address

Github.com/hxyvipno1/m…