Github effect demo: react-demo
Project creation
Create a project folder
mkdir react-demo
cd react-demo
npm init -y
Copy the code
Depend on the installation
yarn add react react-dom
yarn add webpack webpack-cli webpack-dev-server webpack-merge
babel-core babel-loader babel-polyfill babel-preset-env babel-preset-react
babel-preset-stage-0 cross-env
file-loader jsx-loader
css-loader style-loader url-loader less less-loader --dev
Copy the code
Webpack configuration
Distinguish between development environment and production environment. Create corresponding configuration files respectively. Antd-mobile loads them on demand
- Installing a plug-in
yarn add babel-plugin-import -D
Copy the code
- Modify the babel.config.js configuration
module.exports = {
presets: ["@babel/preset-env"."@babel/preset-react"].plugins: [
"@babel/plugin-transform-runtime"."@babel/plugin-proposal-class-properties"["import", { libraryName: "antd-mobile".style: true}}]].Copy the code
Externals configuration
Externals in webpack prevents certain imported packages from being packaged into bundles
modules.export = {
plugins: [
new HtmlWebpackPlugin({
title: 'React Board'.files: { // Configure CDN import
js: [
'//unpkg.com/swiper/js/swiper.min.js'].css: [
'//unpkg.com/swiper/css/swiper.min.css']}})],externals: {
swiper: 'Swiper'}}Copy the code
Index.html Settings:
<html lang="en">
<head>
<meta charset="UTF-8">
<title><% = htmlWebpackPlugin.options.title% ></title>
<! -- require cdn assets css -->
<% for (var i in htmlWebpackPlugin.options.files.css) { %>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.files.css[i] %>" />
<%} % >
</head>
<body>
<div id="root"></div>
<! -- require cdn assets js -->
<% for (var i in htmlWebpackPlugin.options.files.js) { %>
<script type="text/javascript" src="<%= htmlWebpackPlugin.options.files.js[i] %>"></script>
<%} % >
</body>
</html>
Copy the code
Use:
import Swiper from 'swiper';
Copy the code
Mobile adaptation
Use ** postCSs-loader ** to implement CSS conversion
// The project uses less
yarn add postcss-less-loader -D
Copy the code
Webpack. Base. Js configuration
{
test: /\.(css|less)$/.use: [
'style-loader'.'css-loader'.'less-loader'.'postcss-less-loader']}Copy the code
postcss-px-to-viewport
Use this plugin to convert all PX to VW window size
yarn add postcss-px-to-viewport -D
Copy the code
Create postcss.config.js in the project root directory
module.exports = {
plugins: {
"postcss-px-to-viewport": {
viewportWidth: 375.// The width of the window corresponds to the width of our design. Iphone6 is usually 375 (xx/375*100vw).
viewportHeight: 667.// the window height on the Iphone6 is 667
unitPrecision: 3.// Specify the decimal number to convert 'px' to the window unit value (often not divisible)
viewportUnit: "vw".// Specify the window unit to convert to. Vw is recommended
selectorBlackList: ['.ignore'.'.hairlines'].// Specify a class that is not converted to Windows units. It can be customized and added indefinitely. It is recommended to define one or two common class names
minPixelValue: 1.// less than or equal to '1px' does not convert to window units, you can also set to whatever value you want
mediaQuery: false.// Allow conversion of 'px' in media queries
exclude: /(node_module)/i // Ignore the UI component library}}}Copy the code
postcss-plugin-px2rem
This plugin is to convert all PX into REM size units
yarn add postcss-plugin-px2rem -D
Copy the code
Postcss. Config. Js configuration:
module.exports = {
plugins: {
"postcss-plugin-px2rem": {
rootValue: 16.// Use the 750 design draft with rem.js
unitPrecision: 5.mediaQuery: true.exclude: /(node_module)/i.selectorBlackList: ['html'.'mp-'.'calendar'.'iconfont'].// In the rem.js global effect, exclude the influence of the specified file
propBlackList: ['border'] // Filter attributes}}}Copy the code
You need to create rem.js or download lib-Flexible directly
const viewportWidth = 750
// Base size
const baseSize = 32
// Set the rem function
function setRem() {
// The zoom ratio of the current page width to 750 width can be modified according to your needs.
const scale = document.documentElement.clientWidth / viewportWidth
// Set the font size at the root of the page
document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) + 'px'
}
/ / initialization
setRem()
// Resets rem when changing the window size
window.onresize = function () { setRem() }
Copy the code
In the entry file introduce:
// App.js
import './utils/rem'
// import "./utils/flexible.js"
Copy the code
EsLint configuration
Install the ESLint plugin
yarn add eslint eslint-plugin-import babel-eslint eslint-plugin-react-hooks -D
Copy the code
Create the.eslintrc.js configuration file in the root directory
module.exports = {
parser: "babel-eslint".plugins: [
"react-hooks"].rules: {
"react-hooks/rules-of-hooks": "error".// Check the Hook rules
"react-hooks/exhaustive-deps": "error" // Check for effect dependencies}}Copy the code
The React routing
yarn add react-router-dom react-router-config
Copy the code
Use react-router-config to simplify route configuration. Create the routes.js file
import Home from "@/pages/Home"
import Me from "@/pages/Me"
import Test from "@/pages/Test"
console.log(typeof process.env.API)
const routes = [
{
path: "/home".exact: true.component: Home
},
{
path: "/me".exact: true.component: Me
},
{
path: "/test".exact: true.component: Test
}
];
export default routes;
Copy the code
Import route from root file app.js:
import { renderRoutes } from 'react-router-config'
import routes from './routes'
import { HashRouter as Router } from 'react-router-dom'
import Layouts from "./components/Layouts";
function App() {
return (
<Router>
<Layouts>
{renderRoutes(routes)}
</Layouts>
</Router>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
Copy the code
Development of Hooks
What is a Hook? Hook is a special function that lets you “Hook” into the React feature. Hooks can only be declared in Function Component.
useState
Returns a state and a function setter that can modify the state
import React, { useState } from 'react';
import { Button } from "antd-mobile";
function User() {
const [user, setUser] = useState('Mondo')
return (
<div>
<div>{user}</div>
<Button type="primary" onClick={e= >SetUser (' imondo. Cn)} > change the State</Button>
</div>)}Copy the code
useEffect
Replace componentDidMount, componentDidUpdate, componentWillUnmount, etc
import React, { useState, useEffect } from 'react';
function User() {
const [user, setUser] = useState('Mondo')
useEffect((a)= > {
setTimeout((a)= > {
setUser("js.imondo.cn")},2000)
}, [user]) // Update only when user changes
return (
<div>
<div>{user}</div>
<Button type="primary" onClick={e= >SetUser (' imondo. Cn)} > change the State</Button>
</div>)}Copy the code
useContext
Receives a context object and returns the current value of that context. The current context value is determined by the < MyContext.provider > value prop of the upper-layer component closest to the current component. This Hook triggers rerendering when the most recent < myContext. Provider> update is made to the upper layer of the component. Can be used for value passing between components
import React, { useContext } from 'react';
const theme = {
color: "red"
}
const UserContext = React.createContext(theme);
function User() {... return (<UserContext.Provider value={theme}>
<Child/>
</UserContext.Provider>
)
}
function Child() {
const theme = useContext(UserContext);
return (
<div style={{color: theme.color}} >context</div>)}Copy the code
useMemo
UseMemo (() => fn, deps) passes the “create” function and an array of dependencies as arguments to useMemo, which recalcates memoized values only when a dependency changes. This optimization helps avoid costly calculations every time you render. Can be used as a calculated property in vUE
import React, { useState, useMemo } from 'react';
import { Button } from "antd-mobile";
function User() {
const [user, setUser] = useState(1)
/* Cache calculated attributes */
const data = useMemo((a)= > ({
users: (user + 1)
}), [user]);
const onChangeUser = (e) = > {
setUser(+e.target.value);
}
return( <UserContext.Provider> <input value={user} onChange={onChangeUser}/> <div>{data.users}</div> <Button type="primary" OnClick ={e => setUser(user + 1)}> Change State</Button> </ usercontext.provider >)}Copy the code
useReducer
Const [state, dispatch] = useReducer(Reducer, initialArg, init) It is an alternative to useState and is used in some scenarios:
- The state logic is complex and contains multiple child values
- The next state depends on the previous state
The most important thing is that it’s written like **redux **
import React, { useReducer } from "react";
import { Button } from "antd-mobile";
let initCount = 0;
function reducer(state = initCount, action) {
switch (action) {
case "increment":
state++
return state
case "decrement":
state--
return state
default:
throw new Error();
}
}
function User() {
const [count, disaptch] = useReducer(reducer, initCount)
return (
<UserContext.Provider value={theme}>
<div>useReducer</div>
<div>Counter {count}</div>
<Button type="primary" onClick={e= >Disaptch (" decrement ")} ></Button>
<Button type="primary" onClick={e= >> add disaptch (" increment ")}</Button>
</UserContext.Provider>)}Copy the code
useRef
Return a mutable ref object whose.current property is initialized as the parameter passed in. If you want to access a REF object within a child component, the child component needs to declare the component with class.
import React, { useState, useMemo, useRef } from 'react';
function Parent() {
let [count, setCount] = useState(0)
const childRef = useRef(null)
const childClick = (val) = > {
childRef.current.setState({
num: 2
});
}
return (
<div>
<h4>Components by value</h4>
<button onClick={childClick}>Pass values to child components</button>
<Child1 ref={childRef} />
</div>); } class Child1 extends React.Component { constructor() { super(... arguments); this.state = { num: 1 } } render() { const { num } = this.state; return (<div>
<div>Ref components</div>
<div>{num}</div>
</div>)}}Copy the code
Remember to read before writing React Hooks
Welcome to pay attention to the public number, we communicate and progress together.