react 初学遇到的问题

1. useEffect依赖项变化时并没有执行

源码

useEffect(() => {
  const selectedComp = selects.find(select => select.value === selected);
  selectedComp && setSelectedComp(selectedComp);
}, [selected, selects, selectedComp]);

分析

  • 从提供的代码片段来看,这一行代码本身的逻辑是在查找 selects 数组中 value 属性等于 selected 的元素,并将这个元素赋值给状态 selectedComp

  • 这段代码可能出现问题的原因主要可能包括以下几点:

1. 查找结果为 undefined:
  • 如果 selects 数组中没有任何一个元素的 value 属性与 selected 相等,find 方法将返回 undefined 。这可能不是你的预期行为,尤其是如果你后续的代码依赖于 selectedComp 总是一个有效对象的话。确保你的代码能够妥善处理这种情况:

    const selectedComp = selects.find(select => select.value === selected);
    if (selectedComp) {
      setSelectedComp(selectedComp);
    } else {
      // 处理未找到匹配项的情况,例如设置一个默认值或更新状态以反映未找到
    }
    
2. 状态更新异步性
  • setSelectedComp 是一个异步操作,这意味着状态的更新不会立即反映。如果你在调用 setSelectedComp 之后立即依赖于 selectedComp 的新值,可能会遇到问题。React 状态更新可能会被批处理,且实际更新的时机由 React 控制。正确的做法是在另一个 useEffect 中,依赖于 selectedComp 来执行需要该状态更新后的操作:

    useEffect(() => {
      //依赖于 selectedComp 的逻辑
    }, [selectedComp]);
    
3. 检查是否有错误导致中断
  • 如果 useEffect 中的代码抛出了错误,可能会导致后续代码不执行。尽管代码应该在错误之前执行,但值得确认是否有其他代码抛出了错误,特别是如果 selectedCompundefined (即没有找到配的 select ),这可能会导致问题。你可以添加 trycatch 块来捕获并查看是否有错误发生:

    useEffect(() => {
      try {
        const selectedComp = selects.find(select => select.value === selected);
        if (!selectedComp) {
          console.error("未找到匹配的 select");
          return;
        }
        setSelectedComp(selectedComp);
      } catch(error) {
        console.error("useEffect 错误:",error);
      }
    }, [selected, selects])
    

2. 函数获取不到最新的状态值

源码

// 获取答案
const handleGetAnswer = (item: AnswerFields) => {
  const { question, content, faqs } = item;

  // 答案写入 todo...
  setInputValue(question);
  handleSendText();
};
// 发送信息 且机器人回复处理
const handleSendText = async () => {
  if (!inputValue) return;
  // ...
};

分析

  • 此时 handleSendText 函数调用时,期望获得最新的 inputValue 状态值,但此时遇到问题:在 handleSendText 里获取不到最新的 inputValue 值,这是因为状态更新时异步的,而且在 set 之后立即调用的函数内使用的是旧值

解决方案

  • useEffect 中调用 handleSendText 方法

实现方式

  1. 需要增设状态值 shouldSendText 来标记是否需要发送文本

  2. 用户回车且 inputValue 有效时,setShouldSendText(true)

  3. 使用 useEffect 监听 shouldSendText,若为 true 则调用 handleSendText 且设置 setShouleSendText(false)

// 获取答案
const handleGetAnswer = (item: AnswerFields) => {
  const { question, content, faqs } = item;

  // 答案写入 todo...
  setInputValue(question);
  setShouldSendText(true);
};
// 用户回车发送消息
const handleKeyDown = event => {
  if (event.key === 'Enter') {
    setShouldSendText(true);
  }
};
// 发送信息 且机器人回复处理
const handleSendText = async () => {
  setShouldSendText(false);
  if (!inputValue) return;
  // ...
};

useEffect(() => {
  shouldSendText && handleSendText();
}, [shouldSendText]);
posted on 2024-04-29 17:50  pleaseAnswer  阅读(5)  评论(0编辑  收藏  举报