React 实战笔记一
- 参考:王红元老师的React
项目规范
- 1.文件夹、文件名称统一小写、多个单词以连接符(-)连接;
- 2.JavaScript变量名称采用小驼峰标识,常量全部使用大写字母,组件采用大驼峰;
- 3.CSS采用普通CSS和styled-component结合来编写(全局采用普通CSS、局部采用styled-component);
- 4.整个项目不再使用class组件,统一使用函数式组件,并且全面拥抱Hooks;
- 5.所有的函数式组件,为了避免不必要的渲染,全部使用memo进行包裹;
- 6.组件内部的状态,使用useState、useReducer;业务数据全部放在redux中管理;
- 7.函数组件内部基本按照如下顺序编写代码:
- 组件内部state管理;
- redux的hooks代码;
- 其他组件hooks代码;
- 其他逻辑代码;
- 返回JSX代码
- 8.redux代码规范如下:
- 每个模块有自己独立的reducer,通过combineReducer进行合并;
- 异步请求代码使用redux-thunk,并且写在actionCreators中;
- redux直接采用redux hooks方式编写,不再使用connect;
- 9.网络请求采用axios
- 对axios进行二次封装;
- 所有的模块请求会放到一个请求文件中单独管理;
- 10.项目使用AntDesign
- 项目中某些AntDesign中的组件会被拿过来使用;
- 但是多部分组件还是自己进行编写;
- 其他规范在项目中根据实际情况决定和编写;
- 注:为什么看不到react devtools标记
- https://github.com/facebook/react-devtools/issues/191
目录结构
AntDesign安装
CSS 重置
yarn add normalize.css
- 导入使用:
- 全局导入:
@import "~normalize.css";
@import "~antd/dist/antd.css";
/* 样式的重置 */
body, html, h1, h2, h3, h4, h5, h6, ul, ol, li, dl, dt, dd, header, menu, section, p, input, td, th, ins {
padding: 0;
margin: 0;
}
ul, ol, li {
list-style: none;
}
a {
text-decoration: none;
color: #666;
}
a:hover {
color: #666;
text-decoration: underline;
}
i, em {
font-style: normal;
}
input, textarea, button, select, a {
outline: none;
border: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
img {
border: none;
vertical-align: middle;
}
/* 全局样式 */
body, textarea, select, input, button {
font-size: 12px;
color: #333;
font-family: Arial, Helvetica, sans-serif;
background-color: #f5f5f5;
}
.text-nowrap {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.image_cover {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
text-indent: -9999px;
background: url(../img/sprite_cover.png) no-repeat -145px -57px;
}
.sprite_player {
background: url(../img/playbar_sprite.png) no-repeat 0 9999px;
}
.lyric-class .ant-message-notice-content {
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 50px;
background-color: rgba(0, 0, 0, .5);
color: #fff;
}
- 对项目页面进行划分
- 对组件进行实现,建立index.js,对外导出
安装路由
- 注:安装指定版本 react-router-dom@^5 --save
- 参考:npm安装指定版本的react-router-dom - 简书
- 使用:
- 创建具体组件,在路由中进行配置:
- App.js
- 路由使用
- 示例2:
import React, { memo } from 'react';
import { renderRoutes } from 'react-router-config';
import { dicoverMenu } from "@/common/local-data";
import { NavLink } from 'react-router-dom';
import {
DiscoverWrapper,
TopMenu
} from './style';
export default memo(function HYDiscover(props) {
const { route } = props;
return (
<DiscoverWrapper>
<div className="top">
<TopMenu className="wrap-v1">
{
dicoverMenu.map((item, index) => {
return (
<div className="item" key={item.title}>
<NavLink to={item.link}>{item.title}</NavLink>
</div>
)
})
}
</TopMenu>
</div>
{renderRoutes(route.routes)}
</DiscoverWrapper>
)
})
顶部栏组件
- 安装style-components
- 组件加入wrapper,降低冲突:
- 样式设置:
- 顶部数据导入:
网易云API文档
- 网易云音乐 NodeJS 版 API
- 在线Api接口,网易云音乐api数据完整接口文档,QQ音乐在线api接口文档,电商api开放数据接口文档分享,小说ap接口,漫画api接口_梦之所以-CSDN博客_网易云音乐api文档
路由重定向
子路由
- 使用需要安装:
网络请求
- 使用:
使用Redux
ImmutableJS
- 数据的可变引起的问题
- 在React开发中,我们总是会强调数据的不可变性:
- 无论是类组件中的state,还是redux中管理的state;
- 事实上在整个JavaScript编码过程中,数据的不可变性都是非常重要的;
- 数据的可变性引发的问题(案例):
- 我们明明没有修改obj,只是修改了info,但是最终obj也被我们修改掉了;
- 原因非常简单,对象是引用类型,它们指向同一块内存空间,两个引用都可以任意修改;
const info = {
name: "why",
age: 20
}
const obj = info;
info.name = "kobe";
console.log(obj.name); // kobe
- 有没有办法解决上面的问题呢?
- 进行对象的拷贝即可:Object.assign或扩展运算符
- 这种对象的浅拷贝有没有问题呢?
- 从代码的角度来说,没有问题,也解决了我们实际开发中一些潜在风险;
- 从性能的角度来说,有问题,如果对象过于庞大,这种拷贝的方式会带来性能问题以及内存浪费;
认识ImmutableJS
- 为了解决上面的问题,出现了Immutable对象的概念:
- Immutable对象的特点是只要修改了对象,就会返回一个新的对象,旧的对象不会发生改变;
- 但是这样的方式就不会浪费内存了吗?
- 为了节约内存,又出现了一个新的算法:Persistent DataStructure(持久化数据结构或一致性数据结构);
- 当然,我们一听到持久化第一反应应该是数据被保存到本地或者数据库,但是这里并不是这个含义:
- 用一种数据结构来保存数据;
- 当数据被修改时,会返回一个对象,但是新的对象会尽可能的利用之前的数据结构而不会对内存造成浪费;
- 如何做到这一点呢?结构共享
常见API
- 示例:
const im = Immutable;
// Map的使用
const info = {
name: "kobe",
age: 30,
friend: {
name: "james",
age: 25
}
}
const infoIM = im.Map(info);
const obj = infoIM;
const infoIM2 = infoIM.set("name", "why");
console.log(obj.get("name"));
console.log(infoIM2.get("name"));
// List的使用
const names = ["abc", "cba", "nba"];
// const arr = names;
// names[0] = "why";
// console.log(arr);
const namesIM = im.List(names);
const arrIM = namesIM.set(0, "why");
console.log(namesIM.get(0));
console.log(arrIM.get(0));
const info = {
name: "kobe",
age: 30,
friend: {
name: "james",
age: 25
}
}
// const infoIM = im.Map(info);
const infoIM = im.fromJS(info);
console.log(infoIM.get("friend"));
安装
- 设置数据:
- 获取数据:
合并Reducer 需要安装
- 获取: