1. react-i18next resources key默认杠后大写

新增了繁体中文模块,如下导入,切换语言并不生效

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import translation_en from './en';
import translation_zh from './zh';
import translation_zh_traditional from './zh-traditional';

const resources = {
  en: translation_en,
  zh: translation_zh,
  'zh-traditional': translation_zh_traditional,
};

i18n.use(initReactI18next).init({
  resources,
  lng: 'en',
  fallbackLng: 'en',
  interpolation: {
    escapeValue: false,
  },
});

export default i18n;

原来i18next默认杠后面要大写,
image.png
或者配置lowerCaseLng为true,全小写就会生效了

2. 关于使得pdf文档部分高亮的技术选型

需求:点击左边的item,对应右边的pdf高亮显示
image.png

  • react-pdf@7.7.1
    腾讯一篇文章效果像是我们想要的,去翻看其使用到的react-pdf wikiHighlight text on the page,是遍历整个pdf内容,将每块内容切成小块跟你提供的text去匹配,匹配成功则高亮,而我们提供的text一般都是段落很长,这会导致有很多地方的小块内容被text匹配上,从而匹配的结果看起来像是狸花猫,而不是指定的一整块,例如下面的效果:
    image.png
    这不是我们想要的
  • react-pdf-highlighter@6.1.0
    该库通过坐标去高亮pdf,可以很好的实现我们的需求,后端解析文档的段落,将对应的坐标给到前端就可以实现了,但是其中也有坑react-pdf-highlighter@6.1.0 高亮定位不准

3. key的唯一性是多么的重要

神奇的bug出现了,
6aadfae193c24e6447dc13cbfbb7e3c.png

e2ce5fad8e170140c092a052f3bd7b1.png
切换过来 上一条数据还在,上一个对话的内容不应该出现当前的对话里,排查了很久,百思不得其解。

              {conversation?.message?.map((message, i) => {
                return (
                  <MessageItem
                    loading={
                      message.role === MessageType.Assistant &&
                      sendLoading &&
                      conversation?.message.length - 1 === i
                    }
                    key={message.id}
                    item={message}
                    nickname={userInfo.nickname}
                    avatar={userInfo.avatar}
                    reference={buildMessageItemReference(conversation, message)}
                    clickDocumentButton={clickDocumentButton}
                  ></MessageItem>
                );
              })}

还以为我这里遍历的代码有问题,之前都是好好的
2a5d021b6359c5d6e90fba6b934bb7e.png
发现是数据的问题,
0e18a9d5e1d4c9e76d6e9938f81bc3f.png
导致我的组件的key会重复
4d0ff864c576049d91e81fd00cf08d9.png
控制台已经报错了,没放在心上。

4. react 更新查询字符串 (search params)

"umi": "^4.0.90",
用下面的方式更新查询参数

export const useClickConversationCard = () => {
  const [currentQueryParameters, setSearchParams] = useSearchParams();
  const newQueryParameters: URLSearchParams = useMemo(
    () => new URLSearchParams(currentQueryParameters.toString()),
    [currentQueryParameters],
  );

  const handleClickConversation = useCallback(
    (conversationId: string) => {
      newQueryParameters.set(ChatSearchParams.ConversationId, conversationId);
      setSearchParams(newQueryParameters);
    },
    [newQueryParameters, setSearchParams],
  );

  return { handleClickConversation };
};

使用:

  // When you first enter the page, select the top conversation card
  const checkTopConversationCard = useCallback(
    (conversationList: IConversation[]) => {
      const firstConversation = conversationList.at(0);
      if (firstConversation) {
        handleClickConversation(firstConversation.id);
      }
    },
    [handleClickConversation],
  );

  useEffect(() => {
    checkTopConversationCard(conversationList);
  }, [conversationList, checkTopConversationCard]);

image.png
如上图,点击除了第一个以外的对话,始终会选中第一个,逐步排查是handleClickConversation以来的问题,将newQueryParameters从handleClickConversation移除就没问题了。但是我用setSearchParams({ [ChatSearchParams.ConversationId]: conversationId });这种方式会覆盖而不是更新查询参数,查阅资料,Update search params without re-rendering everything #9851 也有类似的讨论,根据React Router V6 手摸手随便指南指北发现,
测试,react-router@v6.26.2

  function handleUpdateParams() {
    setSearchParams((preParams)=>{
      preParams.set("conversationId","10000000000")
      return preParams
    });
  }

回调函数可以实现search params的增量更新,而不是覆盖。

5. useEffect 回调函数返回函数的调用时机

react@18.2.0

import { useCallback, useEffect, useState } from 'react';

const Demo = () => {
  const [answer, setAnswer] = useState('111');

  const handleClick = useCallback(() => {
    setAnswer('');
  }, []);

  const handleChange = useCallback((e: any) => {
    setAnswer(e.target.value);
  }, []);

  useEffect(() => {
    console.log('🚀 ~ useEffect:', answer);

    return () => {
      console.log('🚀 ~ unmount:', answer);
    };
  }, [answer]);

  return (
    <div>
      <input type="text" value={answer} onChange={handleChange} />
      <button type="button" onClick={handleClick}>
        reset
      </button>
    </div>
  );
};

export default Demo;

一直以为useEffect回调函数返回的函数只有在页面卸载的时候才会被调用,直到遇见了个issue,做了测试,每次修改输入框的值,都会先调用返回的函数,再调用回调函数
image.png
查看官方文档
image.png


assassin_cike
1.3k 声望74 粉丝

生活不是得过且过