簡體   English   中英

在 reactjs 中使用 useState 掛鈎更新對象數組

[英]Updating array of objects by using useState hook in reactjs

我有這個 state 的數組 object。我用它們來創建三張卡片。

const [option, setOption] = useState([{
    id: 1,
    label: "Borrowers",
    icon: FcApprove,
    counter: 2,
    link: "borrowers",
    color: "#5d8c6d",
    isActive: false,
  },
  {
    id: 2,
    label: "My Offer",
    icon: FaHandsHelping,
    counter: 2,
    link: "offer",
    color: "#04738a",
    isActive: false,
  },
  {
    id: 3,
    label: "Promise",
    icon: FaPrayingHands,
    counter: 2,
    link: "promise",
    color: "#40437a",
    isActive: false,
  }
]);

每當單擊其中一張卡片時,我想將字段isActive更新為 true,如下所示。

function FixedHeader() {
  const [options, setOptions] = useState(option); //option is the above mentioned array of object
  const handleChange = (opt) => {
    setOption([option[index].isActive: true])
  }
  return < > {
    options.map((opt, index) => {
      <Card onClick={handleChange(opt,index)} key={index} className={opt.isActive ? "activecard": ""}>
        <CardContent>
          <Stack direction="column">
            <opt.icon size={20}/>
            <Typography>opt.label</Typography>
          </Stack>
        </CardContent>
      </Card>
    })
  }

我的代碼有點像上面的代碼。 但它並沒有真正改變isActive歸檔

您正在改變options數組。 當你想更新存儲在 state 中的數組時,你需要創建一個新數組(或復制一個現有數組),然后設置 state 以使用新數組。

下面將解決您的問題

const handleChange = (options, index) => {
  setOption(options.map((option, i) =>  ({...option, isActive: i === index }));
}

options是一個數組。 你會想要 map 之前的 state 數組到下一個 state 數組,通過id屬性更新特定元素 object。

const [options, setOptions] = useState(option);

// Curried function to close over option id in callback scope
const handleChange = (id) => () => {
  setOption(options => options.map(option => option.id === id
    ? { ...option, isActive: true }
    : option
  );
}

options.map((opt) => (
  <Card
    key={opt.id}
    onClick={handleChange(opt.id)}
    className={opt.isActive ? "activecard" : ""}
  >
    <CardContent>
      <Stack direction="column">
        <opt.icon size={20} />
        <Typography>opt.label</Typography>
      </Stack>
    </CardContent>
  </Card>
)

這里有幾個問題,第一個是在更新useState中設置的任何內容時應該使用useCallback掛鈎:

export default function FixedHeader() {
  const [options, setOptions] = useState(myOptions);

  const onClick = useCallback((id) => {
    setOptions(options.map((opt) => {
      if (opt.id === id) {
        opt.isActive = !opt.isActive
      }
      return opt
    })
  )}, [options])

  return (
    <div>
      {
        options.map((option) => (
          <div style={{ backgroundColor: option.isActive ? 'blue' : 'red' }}>
            <button onClick={() => onClick(option.id)}>{option.label}</button>
          </div>
        ))
      }
    </div>
  );
}

請注意,為了測試這一點,我渲染的內容與您不同,因此請確保不是傳遞索引,而是傳遞option.id ,如下所示:

onClick={() => onClick(option.id)}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM