因此,我try 使用setTagList()修改标记列表.它更改了页面内容(它在<Filter/>组件中添加了标记),但我无法实现<Filter/>中的每个标记都是唯一的.

import Filter from "./components/Filter";
import Card from "./components/Card";
import data from "./assets/data.json";
import { useState, useEffect } from "react"


export default function App() { 
  const [cards, setCards] = useState([]);
  const [tagList, setTagList] = useState([]);
  

  useEffect(() => {
    generateCards();
  }, []);

  function addTag(newTag) {
    // console.log(tagList) always outputs []

    if (!tagList.includes(newTag)) {
      setTagList(oldTagList => [...oldTagList, newTag])
      // console.log(tagList) here always outputs []
      // But if I change "const [tagList, setTagList] = useState([]);" to "let [tagList, setTagList] = useState([]);" and add "tagList = [...tagList, newTag]" here, it works
    }  
  }  

  function deleteTag(tag) {
    setTagList((oldTags) => oldTags.filter((oldTag) => oldTag !== tag));
  }

  function clearTags() {
    setTagList([]);
  }

  function generateCards() {
    setCards(
      data.map((cardData) => (
        <Card
          key={cardData.id}
          logo={cardData.logo}
          company={cardData.company}
          isNew={cardData.new}
          isFeatured={cardData.featured}
          position={cardData.position}
          postedAt={cardData.postedAt}
          contract={cardData.contract}
          location={cardData.location}
          tags={[
            cardData.role,
            cardData.level,
            ...cardData.languages,
            ...cardData.tools,
          ]}
          addTag={addTag}
          filter={filter}
        />
      ))
    );
  }

  // console.log(tagList) works normally

  return (
    <div className="bg-bg-color h-screen">
      <div className="relative bg-wave-pattern w-full h-28 text-bg-color bg-primary">
        {tagList.length !== 0 && (
          <Filter tagList={tagList} deleteTag={deleteTag} clearTags={clearTags} />
        )}
      </div>
      <div className="2xl:px-96 xl:px-64 lg:px-32 md:px-16 sm:px-4 py-16 space-y-8">{cards}</div>
    </div>
  );
}

我试图在addTag()函数中整合.log(Taglist),但它总是返回缺省值.但当console.log(Taglist)在函数之外时,它会正常工作. 但是,当我在设置状态时将const关键字更改为let,并在setTagList(...)之后添加"Taglist=[...Taglist,newTag]"时,它起作用了. react 是不是坏了?

推荐答案

这里的问题是,您只能在组件挂载之后更新一次值cards(使用setCards).这是因为您只在带有空依赖数组的useEffect钩子内调用generateCards,因此它只在组件第一次呈现时运行.因为值cards来自第一次渲染,所以赋予每个卡的addTag函数是初始值addTag,它引用初始值tagList(空数组).

虽然您可以通过将tagList添加到useEffect挂钩的依赖项数组来解决此问题,但更直接的处理方法是将addTag的条件逻辑放入传递给setTagList的回调中,如下所示:

function addTag(newTag) {
  setTagList(oldTagList => !oldTagList.includes(newTag) ? [...oldTagList, newTag] : oldTagList);
}

此外,不需要在状态中存储cards,这样做可能会引入您在这里遇到的问题.如果您需要优化性能,您应该使用useMemo,但我将从直接在return语句中呈现卡片开始,如下所示:

export default function App() { 
  const [tagList, setTagList] = useState([]);

  function addTag(newTag) {
    setTagList(oldTagList => !oldTagList.includes(newTag) ? [...oldTagList, newTag] : oldTagList)
  }  

  function deleteTag(tag) {
    setTagList((oldTags) => oldTags.filter((oldTag) => oldTag !== tag));
  }

  function clearTags() {
    setTagList([]);
  }

  return (
    <div className="bg-bg-color h-screen">
      <div className="relative bg-wave-pattern w-full h-28 text-bg-color bg-primary">
        {tagList.length !== 0 && (
          <Filter tagList={tagList} deleteTag={deleteTag} clearTags={clearTags} />
        )}
      </div>
      <div className="2xl:px-96 xl:px-64 lg:px-32 md:px-16 sm:px-4 py-16 space-y-8">
        {data.map((cardData) => (
          <Card
            key={cardData.id}
            logo={cardData.logo}
            company={cardData.company}
            isNew={cardData.new}
            isFeatured={cardData.featured}
            position={cardData.position}
            postedAt={cardData.postedAt}
            contract={cardData.contract}
            location={cardData.location}
            tags={[
              cardData.role,
              cardData.level,
              ...cardData.languages,
              ...cardData.tools,
            ]}
            addTag={addTag}
            filter={filter}
          />
        ))}
      </div>
    </div>
  );
}

Javascript相关问答推荐

如何指定1条记录1个表?

为什么在集内和集外会产生不同的promise 状态(使用Promise.race)?

Express.js:使用Passport.js实现基于角色的身份验证时出现太多重定向问题

Google图表时间轴—更改hAxis文本 colored颜色

MongoDB中的引用

扫描qr code后出错whatter—web.js

在观察框架中搜索CSV数据

Ember.js 5.4更新会话存储时如何更新组件变量

使用原型判断对象是否为类的实例

使用POST请求时,Req.Body为空

将内容大小设置为剩余可用空间,但如果需要,可在div上显示滚动条

在Matter.js中添加从点A到另一个约束的约束

Use Location位置成员在HashRouter内为空

类构造函数忽略Reaction Native中的可选字段,但在浏览器中按预期工作

使用插件构建包含chart.js提供程序的Angular 库?

无法避免UV:flat的插值:非法使用保留字"

在渲染turbo流之后滚动到元素

如何向内部有文本输入字段的HTML表添加行?

ReactJS在类组件中更新上下文

material UI自动完成全宽