前言: 本文仅展示部分基础代码,不涉及原理。
一、 基本目录树
□ public (公共资源文件)
□ nav
□ sprite
- index.html
□ src (源代码)
□ common (公共模块)
□ components (组件/页面)
□ routes (路由文件)
□ style (样式)
□ utils (公共方法)
- App.js
- App.scss
- index.js (入口文件)
- package.json
- README.md
二、 入口文件示例
1. index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render( , document.getElementById('pageWrapper'));
2. App.js
import React from 'react';
import './App.scss';
import { BrowserRouter } from 'react-router-dom';
import { Home } from './routes/Home';
function App() {
return (
);
}
export default App;
三、 路由文件示例
1. routes/Home.js
// 用户登录后的主界面入口模块,界面结构为:左侧菜单栏+顶部导航条+内容区域
function AppContainer() {
// 通常使用现有的UI组件 配合 和组件
// 例
return (
... ...
);
}
export default function Home() {
return (
);
}
2. 路由对应的 组件/页面
- components/Example/Index.js
import React from 'react';
export default function Example() {
return (
我是组件内容
)
};
四、 axios请求示例
1. lib/axios.js 封装axios方法
import Axios from 'axios';
import { request } from './request';
// axios 中间件注册 文档:https://github.com/axios/axios
const axiosInstance = Axios.create();
// 请求拦截示例
axiosInstance.interceptors.request.use(
(config) => {
let { url, data } = config;
const headers = Object.assign({}, config.headers);
// 统一请求网关接口
url = "/gateway";
// 请求头添加公共参数
Object.assign(headers, {
"X-Common-Action": ActionName,
"X-Common-Service": ServiceName,
... ...
});
data = JSON.stringify(data);
Object.assign(config, {
url,
headers,
});
return config;
}, function (error) {
return Promise.reject(error)
}
)
// 响应拦截示例
axiosInstance.interceptors.response.use(
res => {
const { status, data } = res;
if (status === 401) {
window.location.href = '/login';
}
return res;
}, error => {
return Promise.reject(error);
}
);
// 请求体添加公共参数
const mergeParams = (params) => {
const commonParams = {
Version: params.Version,
Action: params.url,
Service: params.name,
};
const proxyObj = {
...params.data,
};
return Object.assign(commonParams, proxyObj);
};
const axios = (config, params) => {
const requestConfig = request(config);
const { method, url, version } = requestConfig;
return axios[method](url, mergeParams({ data: params, ...config }), {
Version: version,
});
};
// get请求 参数格式转换 (转换为 ?key=value&key=value 字符串)
function UrlDataFormat(param) {
const keys = Object.keys(param);
let requestBody = "";
let requestobj = "";
let requestend = "";
let lastrequest = "";
for (let i = 0; i < keys.length; i++) {
if (typeof param[keys[i]] === "object") {
const dd = param[keys[i]];
const keyitems = Object.keys(dd);
for (let k = 0; k < keyitems.length; k++) {
if (typeof dd[keyitems[k]] === "object") {
const keyon = Object.keys(dd[keyitems[k]]);
for (let j = 0; j < keyon.length; j++) {
if (typeof dd[keyitems[k]][keyon[j]] === "object") {
const lastone = Object.keys(dd[keyitems[k]][keyon[j]]);
for (let f = 0; f < lastone.length; f++) {
lastrequest += `${keys[i]}.${keyitems[k]}.${keyon[j]}.${f}=${
dd[keyitems[k]][keyon[j]][f]
}&`;
}
} else {
requestend += `${keys[i]}.${keyitems[k]}.${keyon[j]}=${
dd[keyitems[k]][keyon[j]]
}&`;
}
}
} else {
requestobj += `${keys[i]}.${keyitems[k]}=${dd[keyitems[k]]}&`;
}
}
} else {
requestBody += `${keys[i]}=${param[keys[i]]}&`;
}
}
return `?${requestBody}${requestobj}${requestend}${lastrequest}`;
}
axios.get = (url, params, config) =>
axiosInstance({
method: "get",
url:
url +
UrlDataFormat({
...params,
}),
...config,
})
.then((res) => {
return Promise.resolve(res.data.Response);
})
.catch((err) => {
return Promise.reject(err);
});
axios.post = (url, params, config) => {
return axiosInstance({
method: "post",
url,
data: {
...params,
},
...config,
})
.then((res) => {
return Promise.resolve(res.data.Response);
})
.catch((err) => {
return Promise.reject(err);
});
};
export default axios;
2. lib/request.js (在axios.js文件里有调用request方法)
import apiName from './apiName';
export function request(serviceName) {
const config = apiName[serviceName];
return {
url: `/${config.url}`,
method: config.method,
version: config.version,
}
}
3. lib/apiName.js 配置接口列表
export default {
Login: {
method: "post",
url: "/Login",
version: "0.0.1",
},
...
}
4. store/appApi.js 导出接口调用方法
import axios from "../lib/axios";
export function doLogin(data) {
return axios({ name: "ServerName", url: "Login" }, data)
.then((res) => Promise.resolve(res))
.catch((err) => Promise.reject(err));
}
5. src/Login/Login.js 发起请求
import { doLogin } from '../../store/appApi';
doLogin(data).then(result => {
if (!result.Response.Error) {
history.push('/home'); // 登录成功,跳转到主界面
}
})
五、 context状态管理
1. context/appContext.js 定义context
import React from "react";
export const AppContext = React.createContext({
LoginInfo: {},
setLoginInfo: () => {},
});
2. src/Login/Login.js 使用
import React, { useContext } from "react";
import { AppContext } from "../../context/appContext";
const appContext = useContext(AppContext);
// 更新context状态
appContext.setLoginInfo(Result);
// 获取context状态
console.log(appContext.LoginInfo);
六、 props 父子组件数据传递
1. parent.js 父组件
import React, { useState } from 'react';
import Child from './child'; // 引入子组件
function Parent(){
const [state, setState] = useState(0); // 定义要传递的数据
// 定义要传递的方法
function parentFn(){
// 做某事...
}
return (
);
}
2. child.js 子组件
import React, { useEffect } from 'react';
function Child(props){
useEffect(() => {
console.log(props.state); // 访问父组件的state
props.setState(1); // 修改父组件的state
}, []);
return (
);
}
七、 常用 Hooks 新特性
1. useState
import React, { useState } from 'react';
function Example() {
// ① 定义
const [useName, setUseName] = useState("");
const [age, setAge] = useState(0);
const [list, setList] = useState([]);
// ② 修改
setUseName("小明");
setAge(18);
setList(['吃饭','睡觉']);
return (
姓名: {useName}
年龄: {age}
爱好:
{list.map((item, index) => {
return (
{item}
);
})}
);
}
2. useEffect
import React, { useEffect } from "react";
function Example() {
const [data, setData] = useState([]);
const [params, setParams] = useState({});
useEffect(() => {
setData([]);
}, []); // 参数[] 第一次渲染后,仅调用一次。常用于动态请求数据渲染页面。
useEffect(() => {
setData([]);
}, [params]); // params参数每次改变时都触发调用。
}
3. useRef
import React, { useRef } from 'react';
function Example() {
const divEle = useRef(null); // 定义
useEffect(() => {
console.log(divEle.current); // 访问
}, []);
return (
);
}
4. useRouter
① 页面跳转
import React from 'react';
import useRouter from 'use-react-router';
function Example() {
const { history } = useRouter();
function goHome(){
history.push('/home'); // 跳转到首页
history.push('/home',{ Id: 1 }); // 跳转到首页,并传参数
}
return (
);
}
② 获取传参
import React from 'react';
import useRouter from 'use-react-router';
function Example() {
const { history } = useRouter();
useEffect(() => {
// 获得传递过来的参数
console.log(history.location.state);
console.log(history.location.state.Id);
}, [])
return (
我是首页
);
}