零到一react+ts项目搭建

使用React-create-app搭建react+ts项目

一、create-react-app脚手架

1、依赖安装create-raect-app
在这里插入图片描述
2、项目初始化
**·**快速构建出项目名为react-ts的react+ts的项目
在这里插入图片描述
**·**进入项目可以看到默认已将安装好的部分依赖,此时运行npm run strat命令项目默认会在3000端口地址启动,如下图:
在这里插入图片描述
**·**项目目录结构如下,此时可以删除一些用不上的文件的
在这里插入图片描述
删除之后如下:
在这里插入图片描述
**·**react项目默认隐藏了webpack相关配置文件,如果想要暴露在项目中,需要执行npm run eject,此操作无法回退,根据需要执行;

3、配置路径别名
**·**在引入文件是都是…/ …/…/这种相对路径方式引用可读性很差
**·**安装依赖
在这里插入图片描述

**·**在项目根目录下创建config-overrids.js文件,添加如下配置:
在这里插入图片描述
**·**修改package.json配置,重启项目 npm run serve即可

在这里插入图片描述
**·**此时页面组件引用方式可以由…/方式改为@/方式
在这里插入图片描述

**·**如果提示找不到类型声明,那么就检查tsconfig.json文件看看是否缺配置在这里插入图片描述
二、引入Ant-design组件库
1、安装依赖
在这里插入图片描述
2、在App.tsx文件中引入按钮
**·**查看效果,按钮正常显示说明就是成功了:
在这里插入图片描述
3、语言汉化
**·**使用ConfigProvide包裹App根组件
在这里插入图片描述
**·**在App组件内引入日期选择组件查看效果,可以看到由默认的英文已经切换到中文
在这里插入图片描述
三、引入react路由
1、安装依赖
在这里插入图片描述
2、注册路由
**·**在index.tsx引入并注册路由,这里我们使用history模式
在这里插入图片描述
3、路由跳转例子
**·**在src下新家你pages文件夹,创建两个路由组件,新建routes文件夹,创建index.tsx文件用于存放路由表,引入路由组件并向外暴露,如下:
在这里插入图片描述
**·**为了模拟路由跳转功能,咱们从antd扒一些布局代码,加入到App.tsx组件当中
**·**因为都是写静态的数据,可以自行定义,路由跳转核心是useNavigate,useRouters两个方法,通过useRouters()获取路由表,使用useNavigate()获得navigate函数(navigate是自定义的变量,可以是任意字符串),它接收两个参数,第一个是路径,第二个是可配置对象

import { Layout, theme, Menu } from 'antd';
import type { MenuProps } from 'antd';
import React, { useState } from 'react';
import { UserOutlined, NotificationOutlined, LaptopOutlined } from "@ant-design/icons"
import { useNavigate, useRoutes } from 'react-router-dom';
import routes from './routes';

const { Header, Content, Sider } = Layout

const titleMenu: MenuProps['items'] = ['1', '2', '3'].map((key) => ({
  key,
  label: `标题${key}`
}))

const sideMenu: MenuProps["items"] = [
  {
    key: 'home',
    icon: <UserOutlined />,
    label: '人员管理'
  },
  {
    key: "about",
    icon: <NotificationOutlined />,
    label: "关于系统",
  },
  {
    key: "info",
    icon: <LaptopOutlined />,
    label: "信息管理",
    children: [
      {
        key: "info-detail",
        label: "信息详情"
      },
      {
        key: "info-look",
        label: "信息查询"
      },
    ],
  },
  {
    key: "statistics",
    icon: <NotificationOutlined />,
    label: "数量统计"
  },
]


const App = () => {
  const {
    token: { colorBgContainer },
  } = theme.useToken()
  //获得路由表
  const routeView = useRoutes(routes);
  const navigate = useNavigate()
  //面包屑名称
  const [breadcrumbName, setBreadcrubName] = useState("home");
  //点击菜单
  const handleSiderClick: MenuProps["onClick"] = ({ key, keyPath }) => {
    const name = keyPath.reverse().join("/") || ""
    setBreadcrubName(name)
    if (key !== "home" && key !== "about") return

    //路由跳转
    navigate(key, {
      replace: false,
      state: {
        id: key
      }
    })
  }

  return (
    <Layout>
      <Header className='heder'>
        <div className='logo'>
          <Menu theme='dark' mode='horizontal' defaultSelectedKeys={['1']} items={titleMenu} />
        </div>
      </Header>
      <Layout>
        <Sider width={200} style={{background:colorBgContainer}}>
          <Menu mode="inline" defaultSelectedKeys={["1"]} style={{ height: "100%", borderRight: "0" }} items={sideMenu} onClick={handleSiderClick}></Menu>
        </Sider>
        <Layout style={{padding:"0 24px 24px"}}>
          <div style={{ margin: "16px 0" }}>{breadcrumbName}</div>
          <Content style={{ padding: 24, margin: 0, minHeight: 200, background: colorBgContainer }}>
            { routeView}
          </Content>
        </Layout>
      </Layout>
    </Layout>
  );
}

export default App;

**·**最后运行起来就像这样
在这里插入图片描述
四、引入状态管理集redux
**·**如果你使用过vue,那么你一定知道vuex或是pina,他们核心就是方便各组件的数据共享,同时也是组件通信方式之一
**·**另外,redux并不是单纯为react使用的js库,其他框架也能使用,但是react框架通常使用它作为状态管理集

1、依赖安装
在这里插入图片描述
2、关于react-redux
**·**除了redux,还安装了react-redux,这个库能为我们监测redux数据的变化,从而进行数据更新,因为redux本身不会监测数据变化,手动检测redux数据方式需要使用store实例上的subscribe方法,这里就不模拟了,另外react-redux提供了Provider方便将store实例注入所有组件
**·**关于react-redux的相关概念文档传送门,核心就是引入容器组件和展示组件的概念,它 把需要使用redux数据的组件称为容器组件,在容器组件中,可以使用redux任意的api,方便进行共享数据的获取和操作
**·**总结下,容器组件咱们挡在containers文件夹下,展示组件放在聪明components文件夹,路由租价你放在pages文件夹

3、例子准备
**·**接下来咱们实现一个crud的例子,在src下新建一个contailers文件夹用于存放容器组件,自行创建两个容器组件,我这里叫Count(加减计数的简单组件)和Tiger(展示列表信息的组件),在App.tsx组件中引入
**·**在src目录下新建redux文件夹,并且在此文件夹下新建
1).reducers文件夹,该文件夹下存储容器组件修改数据的方法,并且每个reducer函数都必须四纯函数
2).actions文件夹,存放容器组件对数据操作的方法,例如新增、修改、删除等操作
3).创建store.ts文件,用于创建store仓库
4、组件实例
4.1 Count容器组件相关
**·**在actions文件夹下新增count.ts文件,定义新增,删除方法

export const increment = (data: any) => ({ type: "increment", data })
export const decrement = (data: any) => ({ type: "decrement", data })

//模拟异步操作
export const incrementAsync = (data: any, delay = 500) => {
    return (dispatch: (arg0: { type: string; data: any }) => void) => { 
        setTimeout(() => { 
            dispatch(increment(data))
        },delay)
    }
 }

**·**在reducers文件夹下新增counts.ts文件,定义修改数据的方法
**·**函数接收两个参数,分别为之前的状态(preState默认定义为0,否则初始值没有的话默认为undefined)动作对象(action包含type和data)

export default function countReducer(
    preState = 0,
    action: { type: string; data: any }
): number { 
    const { type, data } = action
    switch (type) {
        case "increment":
            return preState + data
            break;
        case "decrement":
            return preState - data
        default:
            return preState
    }
}
**·**在Count容器组件添加相关代码以及引入redux
import { Button, Select } from "antd";
import React, { useState } from "react";
import { connect } from "react-redux";

import { increment, decrement, incrementAsync } from "@/redux/actions/count";



const Count: React.FC< {
    increment: Function
    decrement: Function
    incrementAsync: Function
    count: number
}> = ( { increment, decrement, incrementAsync, count }) => {
    const [selectNum, setSelectNum] = useState("1")

    const add = () => {
        increment(Number(selectNum))
    }

    const del = () => {
        decrement(Number(selectNum))
    }

    const addAsync = () => {
        incrementAsync(Number(selectNum))
    }

    //切换数字
    const handleSelectChange = (value: string) => {
        setSelectNum(value)
    }

    return (
        <div>
            <h1>总是为:{count}</h1>
            <Select
                defaultValue={"1"}
                style={{ width: 150 }}
                onChange={handleSelectChange}
                options={[
                    { value: "1", label: "1" },
                    { value: "2", label: "2" },
                    { value: "3", label: "3" }
                ]}
            />
            <p>
                <Button onClick={add}>+</Button>
                <Button style={{ margin: "0 8px" }} onClick={del}>-</Button>
                <Button onClick={addAsync}>异步加</Button>
            </p>
        </div>
    )
}

export default connect((state: { count: number }) => ({ count: state.count }), {
    increment,
    decrement,
    incrementAsync
})(Count)

4.2 Tiger容器相关组件
**·**action

import { TigerVo } from "../reducers/tiger";

export const increTIger = (data: TigerVo) => ({ type: "add", data })
export const delTigerById = (data: TigerVo) => ({type:"del", data})

· reducer
关于数组的操作,因为reducer需要是一个纯函数
纯函数原则:
a.不得改写参数数据【unshift方式改写原参数preState】
b.不会产出副作用,例如网络请求,输入输出
c.不能调用Date.now()或Math.random()


export interface TigerVo { 
    id: string;
    name?: string;
    age?:number
}

const initList: TigerVo[] = [
    {
        id: "001",
        name: '邹邹',
        age:30
    },
]

export default function tigerReducer(
    preState = initList,
    action: { type: string; data: TigerVo }
) { 
    const { type, data } = action
    
    switch (type) {
        case "add":
            //preState.unshift(darta) 操作上来说和【preState,...initList】是等价的
            //但是【preState,...initList】此方式返回的是一个新的数组, 不会影响元数组
            return [data,...preState]
            break;
        case "del":
            return [data, ...preState]
        default:
            return preState;
    }
}

· 在Tiger组件添加样式代码,展示数据,同时通过redux能够实现数据源的共享,因此在Tiger组件中也能够拿到Count组件的总数进行展示

import { increTiger, delTigerById } from '../../redux/actions/tiger'
import { connect } from 'react-redux'
import { TigerVo } from '../../redux/reducers/tiger'
import { Button, List, Typography } from 'antd'
// 用于生成唯一标识的id,使用npm i nanoid进行安装;或者自行定义唯一key值也可以
import { nanoid } from 'nanoid'

function Tiger(props: {
  increTiger: Function
  delTigerById: Function
  tigerArr: TigerVo[]
  countNum?: number
}) {
  const add = () => {
    const obj = {
      id: nanoid(),
      name: '雄狮院长',
      age: 7,
    }
    props.increTiger(obj)
  }
  const delOne = (id: string) => {
    props.delTigerById({ id })
  }
  return (
    <List
      header={
        <div>
          <Button type='primary' onClick={add}>
            添加一个
          </Button>
          <div>
            展示一下<strong>Count组件</strong>的总数: {props.countNum}
          </div>
        </div>
      }
      bordered
      dataSource={props.tigerArr}
      renderItem={(item) => (
        <List.Item key={item.id}>
          <Typography.Text mark>ID</Typography.Text>
          {item.id}---
          <Typography.Text mark>名称:</Typography.Text>
          {item.name} ---
          <Typography.Text mark>年龄:</Typography.Text>
          {item.age}
          <Button
            type='primary'
            danger
            style={{ marginLeft: '20px' }}
            onClick={() => delOne(item.id)}
            >
            删除
          </Button>
        </List.Item>
      )}
      />
  )
}

export default connect(
  (state: { tigerArr: TigerVo[]; count: number }) => ({
    tigerArr: state.tigerArr,
    countNum: state.count,
  }),
  {
    // 此处定义的名称就是组件调用方法时的名称
    increTiger,
    delTigerById,
  }
)(Tiger)

4.3 统一暴露所有reducer文件
在reducers文件夹下新建index.ts文件,同意暴露所有reducer集合,需要使用combineReducers方法

import { combineReducers } from 'redux'
import countReducer from './count'
import tigerReducer from './tiger'

// 合并所有reducers
export default combineReducers({
  count: countReducer,
  tigerArr: tigerReducer,
})

4.4 创建store实例
在store.ts文件中创建store实例,通过createStore方法创建
考虑到异步操作,需要银日redux-thunk中间件来支持actions中异步操作,着情况在count组件的sction中存在

// 引入api,creatStore用于创建store对象
import { legacy_createStore as createStore, applyMiddleware } from 'redux'
import allReducers from './reducers/index'
import thunk from 'redux-thunk'
export default createStore(allReducers, applyMiddleware(thunk))

4.5 为组件注入store实例
打开项目入口文件,index.tsx,使用Provider包裹App组件,通过prop的方式传入store
在这里插入图片描述
4.6 实现效果
在这里插入图片描述

### 回答1: 好的,我可以回答这个问题。React TS 项目框架可以使用 Create React App 来创建,然后在其中添加 TypeScript 支持。另外,可以使用 Redux 或 MobX 等状态管理库来管理应用程序的状态。还可以使用 React Router 来处理路由。此外,可以使用 Axios 或 Fetch 等库来处理数据请求。最后,可以使用 Jest 或 Enzyme 等测试库来编写测试用例。 ### 回答2: React TS项目框架可以基于现有的脚手架工具来创建,如Create React App(CRA)。 首先,我们需要安装Node.js和npm(Node Package Manager)。然后,在命令行中运行以下命令来创建一个新的React TS项目: ``` npx create-react-app my-app --template typescript ``` 这将在当前目录下创建一个名为my-app的新项目,并使用TypeScript模板。 接下来,进入my-app目录,并打开一个编辑器。在src目录下,可以看到一个名为index.tsx的文件,这是React组件的入口文件。我们可以在这个文件中开始编写我们的应用程序。 删除不需要的代码,并添加自己的组件和逻辑。可以使用JSX语法编写组件,并使用TypeScript来进行类型检查。在编写组件时,还可以使用React的钩子函数(Hooks)来管理组件状态和生命周期。 此外,还可以根据项目需求安装其他依赖项,如UI组件库、数据管理库等。可以使用npm或者yarn来安装这些依赖项,并在代码中按需引入和使用。 当准备好运行项目时,只需在命令行中运行以下命令: ``` npm start ``` 这将启动一个开发服务器,并在浏览器中打开一个新的标签页,显示你的应用程序。每当进行代码更改时,服务器会自动重新加载应用程序,以便立即看到更改效果。 在开发完成后,可以运行以下命令来构建应用程序的生产版本: ``` npm run build ``` 这将在build目录中生成一个优化过的、供生产环境使用的应用程序。 以上就是一个简单的React TS项目框架的创建过程。根据具体项目需求,可以继续定制和扩展框架,以满足开发需求。 ### 回答3: React是一个非常受欢迎的JavaScript库,用于构建用户界面。而TypeScript是一种强类型的JavaScript超集,它提供了更好的开发工具和编译时错误检查。结合React和TypeScript,可以创建更可靠、可维护和可扩展的项目。 以下是一个适用于React TypeScript项目的基本框架: 1. 安装项目依赖:首先,需要安装React和TypeScript的相关依赖。可以使用npm或yarn命令来安装,例如: ``` npx create-react-app my-app --template typescript ``` 这将创建一个新的React TypeScript项目。 2. 文件结构:创建一个适当的文件结构来组织你的代码。以下是一个示例文件结构: ``` - src - components:存放React组件 - pages:存放页面组件 - styles:存放样式文件 - utils:存放工具函数 - App.tsx:React应用的入口文件 - index.tsx:React渲染的入口文件 ``` 3. 编写组件:开始编写React组件。使用TypeScript的类型注解来定义组件的Props类型,并使用React的函数式组件或类组件来实现组件的逻辑。 4. 使用Hook:React提供了许多有用的Hook,如useState、useEffect等。它们可以在函数式组件中使用,并提供了更好的状态管理和生命周期管理。 5. 使用CSS模块化:使用CSS模块化来组织和管理你的样式文件。在TypeScript项目中,可以使用`.module.css`或`.module.scss`来定义模块化样式。 6. 添加路由:如果需要创建多页面应用,可以使用React Router添加路由功能。React Router提供了一个简单易用的API来实现页面之间的导航。 7. 使用Redux:如果需要全局状态管理,可以考虑使用Redux。Redux与React结合使用,可以更好地管理和共享应用程序的状态。 8. 运行项目:在项目根目录下运行`npm start`或`yarn start`命令来启动开发服务器,预览你的React TypeScript应用。 以上是一个简单的React TypeScript项目框架。根据具体的项目需求,你还可以添加更多的功能和工具库来提高开发效率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值