1. Create a new react+ts project
npx create-react-app <appname> --template typescript
2. push the new local project to the remote warehouse New remote warehouse Open the local project directory and add all the existing files in the current directory to the newly created git warehouse Execute git add Submit the added documents and write the description information git commit -m "item init" Associate a local warehouse with a remote warehouse git remote add origin push the contents of the local warehouse to the remote warehouse git push -u origin master 3. Modify tsconfig JSON file add to "baseUrl": "./src", / / configure absolute path pointing Note: (4-6) steps can be omitted (it is part of the format configuration engineering submission specification, which is not clarified for the time being, which is prone to errors, and will be supplemented later) 4. Install the formatting tool Prettier yarn add --dev --exact prettier Create format profile echo {}> .prettierrc.json New prettierignore file .prettierignore Fill in the following contents: Ignore artifacts: build coverage After that, you can use yarn prettier --write To format the code During team collaborative development, in order to unify and automate the code format before submission Need to use pre commit hook implement npx mrm@2 lint-staged Will be in package One more line of JavaScript in the file prepare": "husky install" "devDependencies": { "husky": "^7.0.4", "lint-staged": "^12.3.4", "prettier": "2.5.1" }, This indicates the file suffix to be formatted. We need to add the suffix at the end of TS and TSX "lint-staged": { "*.{js,css,md,ts,tsx}": "prettier --write" } To be generated Add husky directory to git 5. Because the creation of the project itself will have eslint configuration, which will conflict with our prettier configuration Therefore, it needs to be specially configured for eslint npm install --save-dev eslint-config-prettier After the installation is completed, click package Modify JSON and add prettier to eslint "eslintConfig": { "extends": [ "react-app", "react-app/jest", "prettier" ]/ / indicates that the prettier rule overrides some of the eslint rules }, 6. Configure the commitlint specification project -- check whether the commit message complies with the specification npm install --save-dev @commitlint/config-conventional @commitlint/cli Add commitlint config. JS file definition specification. Because the file encoding format created by the following command is not utf-8, an error may be reported when submitting. Therefore, it is recommended to manually create commitlint config. JS file, copy and paste module exports = {extends: ['@commitlint/config-conventional']}; echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js npx husky add . Husky / commit MSG 'NPX -- no -- commitlint -- edit "$1"' will be in Add a new commit MSG file in husky directory Use this command to cancel verification: git commit -m "project list" -- no verify 7. Installation json-server NPM install - G JSON server global installation NPM install JSON server - D project Create a new directory json_server_mock __ Indicates the directory where the secondary exists __json_server_mock__ Create dB. In this directory JSON file You can fill in the contents, such as { "users":[] } Modify package Add "JSON server" to the scripts of the JSON file: "JSON server _json_server _mock_/ db.json -- watch" "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "prepare": "husky install", "json-server": "json-server __json_server_mock__/db.json --watch --port 3001" } --Port specifies the port number Finally, execute NPM run JSON server to start the mock service 8. Create Env and env. Developep files Configure the interface api request address react in it_ APP_ api_ URL = http://localhost:3001 When quoting: const apiUrl = process.env.REACT_APP_API_URL 9. The parameter is null when the haircut request is processed fetch(`${apiUrl}/projects?name=${param.name}&personId=${param.personId}`) Create a new utils directory under src New index JS file, as follows: export const isFalsy = (value) => value === 0 ? false: ! Value / / judge the bool value of the parameter after excluding 0 //In a function, changing the incoming object itself is not good export const cleanObject = (object) =>{ // Object.assign({},object) const result = {...object} Object.keys(result ).forEach(key=>{ const value = result [key] if(isFalsy(value)) { delete result[key] } }) return result } Install qs plug-in npm install qs --save-dev Replace the final request path with: fetch(`${apiUrl}/projects?${qs.stringify(cleanObject(param))}`)
The final file directory
Use jsonServer to make mock requests. A small demo is written below
db.json:
{ "users": [ { "id": 1, "name": "Gao Xiuwen" }, { "id": 2, "name": "Xiong Tiancheng" }, { "id": 3, "name": "Zheng Hua" }, { "id": 4, "name": "Wang Wenjing" } ], "projects": [ { "id": 1, "name": "Rider management", "personId": 1, "organization": "Takeout group", "created": 1604989757139 }, { "id": 2, "name": "Group buying APP", "personId": 2, "organization": "Group buying group", "created": 1604989757139 }, { "id": 3, "name": "Material management system", "personId": 2, "organization": "Material group", "created": 1546300800000 }, { "id": 4, "name": "Headquarters management system", "personId": 3, "organization": "headquarters", "created": 1604980000011 }, { "id": 5, "name": "Meal delivery route planning system", "personId": 4, "organization": "Takeout group", "created": 1546900800000 } ] }
index.jsx:
import React from "react"; import {cleanObject} from "../../utils"; import {SearchPanel} from "./search-panel"; import {List} from "./list"; import * as qs from "qs"; import {useEffect, useState} from "react"; const apiUrl = process.env.REACT_APP_API_URL export const ProjectListScreen = () => { const [param, setParam] = useState({ name: '', personId: '' }) const [users, setUsers] = useState([]) const [list, setList] = useState([]) useEffect(() => { fetch(`${apiUrl}/projects?${qs.stringify(cleanObject(param))}`).then(async response => { console.log(response) if (response.ok) { setList(await response.json()) } }) }, [param]) useEffect(() => { fetch(`${apiUrl}/users`).then(async response => { console.log(response) if (response.ok) { setUsers(await response.json()) } }) },[]) return <div> <SearchPanel param={param} setParam={setParam} users={users}/> <List list={list} users={users}/> </div> }
list.jsx:
import React from "react"; export const List = ({list, users}) => { return <table className={'my-table'}> <thead> <tr> <th>name</th> <th>person in charge</th> </tr> </thead> <tbody> { list.map(project => <tr key={project.id}> <td>{project.name}</td> <td>{users.find(user => user.id === project.personId)?.name || 'unknown'}</td> {/*{?.name Indicates that name} is displayed when the content of the previous expression is true*/} </tr>) } </tbody> </table> }
searh-panel.jsx
import React from "react"; import {useEffect, useState} from "react"; export const SearchPanel = ({param,setParam,users}) => { return <form action=""> <div> {/*{setParam(Object.assign({},param,{name:evt.target.value}))}*/} <input type="text" value={param.name} onChange={evt => setParam({ ...param, name: evt.target.value }) }/> <select value={param.personId} onChange={evt => setParam({ ...param, personId: evt.target.value })}> <option value={''}>person in charge</option> { users.map(user => <option value={user.id} key={user.id}>{user.name}</option>) } </select> </div> </form> }
App.tsx:
import React from 'react'; import './App.css'; import {ProjectListScreen} from "./screens/project-list"; function App() { return ( <div className="App"> <ProjectListScreen/> </div> ); } export default App;