React,网易云音乐项目(react18,又好像没关系)

3月底,React发布了新版本,于是这几天也在学习react,然后就写了一个音乐项目。下面就来介绍一下吧。

请访问github,项目地址

项目目录

image.png

初始化默认css样式

这里我们使用normalize.css

安装

    npm install normalize.css
复制代码

配置路径别名

这里我们需要拿到webpack配置文件,但是我们也可以使用一个库,最后他会将配置文件中的代码合并到webpack中。

安装 craco 并修改 package.json 里的 scripts 属性。

    npm install @craco/craco
复制代码

package.json

    /* package.json */
    "scripts": {
    -   "start": "react-scripts start",
    -   "build": "react-scripts build",
    -   "test": "react-scripts test",
    +   "start": "craco start",
    +   "build": "craco build",
    +   "test": "craco test",
    }
复制代码

然后在项目根目录创建一个 craco.config.js 用于修改默认配置。

    const {resolve}  = require("path")

    module.exports = {
      webpack: {
        alias: {
          "@": resolve(__dirname, "src"),
          "components": resolve(__dirname, "src/components"),
          "assets": resolve(__dirname, "src/assets"),
          "pages": resolve(__dirname, "src/pages"),
          "http": resolve(__dirname, "src/http"),
          "utils": resolve(__dirname, "src/utils"),
        }
      }
    };
复制代码

数据管理

所以的数据都放在redux中管理,并且使用react-redux提供的hooks。

我们知道,reducer函数是一个纯函数,所以一般我们都会先拷贝以前的state数据,然后在做修改。但是这样对于数据量较大的对象来说,无疑是一种内存浪费。所以我们就可以使用ImmutableJS来解决这一问题。

ImmutableJS介绍

Immutable对象的特点是只要修改了对象,就会返回一个新的对象,旧的对象不会发生改变。

但是这样的方式就不会浪费内存了吗?

为了节约内存,又出现了一个新的算法:Persistent Data Structure(持久化数据结构或一致性数据结构)。

  • 用一种数据结构来保存数据。
  • 当数据被修改时,会返回一个对象,但是新的对象会尽可能的利用之前的数据结构而不会对内存造成浪费。

具体用法和介绍,请访问官网

编写项目是遇到的样式问题

flex: 1对于省略号的理解

我们知道,添加文本省略号的要素

  • 设置元素的宽度
  • 设置元素不允许换行
  • 设置超出文本省略号

单行文本省略

.text-nowrap {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}
复制代码

多行省略号

.text-more-line-nowrap {
  overflow:hidden;
  text-overflow:ellipsis;
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
}
复制代码

我们知道flex: 1设置后,设置flex盒子其他元素的宽度后,那么设置flex: 1的元素将占满整个剩余空间。但是这个是相对宽度。当我们添加文本省略号时,将它作为元素宽度,是不会有省略号效果的,文本依旧会超出容器。 image.png

td中设置flex布局,会破坏布局

<td class="body-title">
    {index < 3 ? (
      <img
        src={getSizeImage(item.al.picUrl, 50)}
        alt={item.name}
      />
    ) : null}
    <div className="body-title-info">
      <div className="btn-play"></div>
      <div className="info-name">{item.name}</div>
    </div>
</td>
复制代码
    .body-title {
      display: flex;
    }
复制代码

image.png 所以,我们做好在td中使用div包裹元素,然后做flex布局。

在自定义便签上写的className默认是无效的。

当我们想要在自定义标签上设置className来完成,我们特定的样式布局。该类名是无效的。

   <SongsListWrapper className="wrap-v2 ===">
      {playListCategoryList.length &&
        playListCategoryList.map((item) => {
          return (
            <MusicItem
              key={item.id}
              musicItemData={item}
              className="music-list-item"
            />
          )
        })}
    </SongsListWrapper>
复制代码

image.png 所以,我们做样式定制,还需要设置props,将值传入到子组件中设置。

table表格th,td设置宽度无效

在做项目的时候,给table的td,th设置宽度,不生效。 image.png 所以需要将table加上

   table-layout:fixed; 
复制代码

编写项目时遇到的逻辑问题

被路由包裹的NavLink在指定路径问题

当我们在子路由中设置NavLink跳转时,他的路径不需要携带父路由路径,不然会多余。

    <NavLink to={`discover/toplist?id=${item.id}`}>
      <img
        src={getSizeImage(item.coverImgUrl, 40)}
        alt={item.commentThreadId}
      />
    </NavLink>
复制代码

image.png

在请求歌单详细数据时,重新刷新不会请求数据

这个不是不能请求的问题,只是我们渲染的时候,取每个元素,不能获取。会报错。所以报错就出现一种错觉。 image.png 所以在渲染元素时,注意加上逻辑判断。

部分页面展示

推荐

image.png

歌单

image.png

歌曲详情

image.png .... 这几天的时间,做了一些页面,主要是为了复习一下react知识。因为第一次学习react还是在大一,然后这两年一直在学习vue。把它丢下来了。现在捡起来,统统吃下。加油,xdm。

猜你喜欢

转载自juejin.im/post/7083120349570662437