杂谈2


解决eslint和prettier冲突

原因:eslint格式化部分的规则和 prettier不兼容。

eslint-config-prettier + eslint-plugin-prettier。

eslint-config-prettier:关闭eslint中与prettier相互冲突的规则。
eslint-plugin-prettier:赋予eslint用prettier格式化代码的能力

修改.eslintrc文件
    "extends": [
        "airbnb",
        "plugin:@typescript-eslint/recommended",
        // 使用来自@typescript-eslint/eslint-plugin的推荐规则
        "plugin:prettier/recommended"
    ],
参考资料: https://blog.csdn.net/songmeinuo/article/details/125297223

hexo 博客添加评论

前言: 很多hexo内置的评论都用不了,即使写了相关配置,但真正评论的时候又出问题。

解决:使用 LeanCloud Valine 评论
1.注册 LeanCloud

2.创建应用 (名随便起)

3.创建完成找到设置

4.安全中心,把自己博客地址添加到安全中心并保存

5.安全中心的应用凭证 复制 AppID 和 AppKey 添加到博客的 Valine 相应的AppID 和 AppKey 下面, Valine 设置为true

就发现评论能用了,历史评论也能保存下来。

参考资料: 

https://zhuanlan.zhihu.com/p/361136001

hexo 博客搭建介绍

https://mp.weixin.qq.com/s?__biz=MzI2MjA1MzM5Nw==&mid=2247485670&idx=1&sn=96d5f0fa44bf4a185002cf18740e92cf&chksm=ea50439cdd27ca8a7be2e8db9f0f84be251b4becc6a955d2e9ed9c8423bc097d189cef3151d2&scene=27

typescript给对象分配键更优雅的做法

export const ROUTERPATH: { [x: string]: string } = {
  推荐: "recommend",
  排行榜: "Ranking",
  电台: "RadioStation",
};

navigate(ROUTERPATH[e.key]);

// 这样就不用再去定义额外的type了

将一首歌曲的所有作者拼接在一起

完全不需要套标签

直接字符串接上 是最简单、最快的方式
    const authAndtime = ar.map((ele: any, index: number) => {
      if (index === 0) {
        return ele.name + "  ";
      }
      return "/" + "  " + ele.name;
<div>{authAndtime}</div>

redux-tookit 状态持久化

前言: 

无论是 vuex 还是 redux 所存储的数据,刷新页面数据都会丢失

为此他们也都有大同小异的解决方案,

就是利用插件,

本质上其实是利用浏览器本地存储。

根据插件相关的配置,

设置需要持久化的数据,

需要、不需要的 设置白 \ 黑名单。

这里只介绍 redux-tookit 持久化插件的用法。
// store.ts

import {
  configureStore,
  ThunkAction,
  Action,
  combineReducers,
} from "@reduxjs/toolkit";

import { persistReducer, persistStore } from "redux-persist";
import storage from "redux-persist/lib/storage";

import playReducer from "./play";
import loginReducer from "./login";
import songsReducer from "./songs";

const rootReducer = combineReducers({
  play: playReducer,
  login: loginReducer,
  songs: songsReducer,
});

// 状态持久化配置
const persistConfig = {
  key: "root",
  storage,
  // 注意: 这里的黑名单是 playSlice 的 name 值 ; 写在这块的数据不会存在storage
  blacklist: ["play"],
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

const store = configureStore({
  reducer: persistedReducer,
});

export type RootState = ReturnType<typeof store.getState>;
export type AppThunk<ReturnType = void> = ThunkAction<
  ReturnType,
  RootState,
  unknown,
  Action<string>
>;

// 持久化store
export const persist = persistStore(store);

export default store;
// 根组件

import { Provider } from "react-redux";
import store, { persist } from "../store";
import { PersistGate } from "redux-persist/integration/react";

// 需要 在 redux 的 Provider 标签内再包一层 PersistGate 持久化 的 标签
const Entries = () => {
  return (
    <Provider store={store}>
      <PersistGate persistor={persist}>
                ...
        ..
        .
      </PersistGate>
    </Provider>
  );
};

export default Entries;
redux 状态持久化 与 tookit 差不多,这里不做展示

参考资料: 

https://blog.csdn.net/qq_60976312/article/details/125690408

https://blog.csdn.net/weixin_43026567/article/details/126864908

hooks依赖项的坑

import {
  useSongComment,
  useSongDetail,
  useSonglyric,
  useSongsimi,
  useSongUrl,
} from "./utils";
import { PLAYCONSTANTS, COMMENT } from "./contants";

export const useSongs = (songId?: number) => {
  // 这里的if 会导致react hook数组发生变化 引发bug!经验证确认!
  // Uncaught TypeError: Cannot read properties of undefined (reading 'length')
  // Warning: React has detected a change in the order of Hooks called by PlayFooter. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks
  // 注释掉就不会报错了
  // if (!songId)
  //   return {
  //     data: [],
  //     name: "",
  //     picUrl: "",
  //     authName: "",
  //     lyric: "",
  //     songs: [],
  //     comments: [],
  //     userId: 0,
  //     topComments: [],
  //   };
  
  const { data: { data = [{ url: "" }] } = {} } = useSongUrl(songId);
  const {
    data: {
      songs: [
        {
          al: { name, picUrl },
          ar: [{ name: authName }],
        },
      ],
    } = PLAYCONSTANTS,
  } = useSongDetail(songId);

  const { data: { lrc: { lyric } } = { lrc: { lyric: "" } } } =
    useSonglyric(songId);

  const { data: { songs } = { songs: [] } } = useSongsimi(songId);

  const { data: { hotComments, comments, userId, topComments } = COMMENT } =
    useSongComment(songId);

  return {
    data,
    name,
    picUrl,
    authName,
    lyric,
    songs,
    hotComments,
    comments,
    userId,
    topComments,
  };
};

为children 添加属性

前言:

一般 children 属性是react的子节点,

我们在jsx 中使用 {} 包裹 children 就可以把这些节点渲染出来,

那么如果我们在组件封装的时候还想为这些children添加一下额外属性,

要怎么做呢?

使用 React.cloneElement!
  const addConfig = (item: any, index: number, children: React.ReactNode) => {
    // 使用 React.cloneElement 最好和 React.isValidElement 一起配合使用
    // 可以避免报错,也可以兼容类型问题,isValidElement 指定的类型会同样赋给cloneElement的类型
    
    if (React.isValidElement<childrenReturnType>(children)) { // children 被克隆的元素
      return React.cloneElement(children, { // 额外添加的属性
        ...item,
        key: item.id,
        songIndex: index,
        songIdList: songIdList,
        customRender: many?.renderFunc,
      });
    }
    console.error("CardList 必须传入react元素!");
  };
// 渲染 克隆后的元素

<List.Item>
    {addConfig(item, index, children)}
</List.Item>

react 循环id元素的子节点

const div = document.getElementById("lyricdiv");

[...div.children].forEach((item) => {
  ...
  ..
  .
});
// 需要再tsconfig compilerOptions 下 加入如下配置

"downlevelIteration": true, //使 [...div.children]这种写法不报错

文章作者: KarlFranz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 reprint policy. If reproduced, please indicate source KarlFranz !
评论
  目录