reactjs React -对数组使用状态-不“取”第一项

wkftcu5l  于 2023-03-17  发布在  React
关注(0)|答案(2)|浏览(141)

我可能遗漏了一些东西(几乎可以肯定),但是当我“设置”一个state数组时,如果数组只有一个项,state,则为空;如果我“设置”一个有多个项的数组,state数组就会少一个项。
可能最好显示一个样本。(手表控制台)。
codesandbox

import React, {useState} from "react";
import "./styles.css";
import Select from "react-select";

export default function App() {
  const [items, setItems] = useState([]);

  const options = [
    {value: 1, label: "Item 1"},
    {value: 2, label: "Item 2"},
    {value: 3, label: "Item 3"},
    ]

  function hanldeItemChange(selectedItems) {
    //This prints all object in console
    console.log(`selectedItems = ${selectedItems}`);
    var mappedItems = selectedItems.map(item => item.value);
    //This prints just the values as an array (correctly)
    console.log(`mappedItems = ${mappedItems}`);
    setItems(mappedItems);
    //This print the values from my state array, but it does not match the "MappedItems"
    console.log(`items = ${items}`);
  }

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Select
          className="basic-multi-select"
          classNamePrefix="select"
          onChange={hanldeItemChange}
          isMulti
          name="Items"
          options={options}
        />

    </div>
  );
}
k2fxgqgv

k2fxgqgv1#

我误解了useState是如何工作的。正如Nijat所建议的,使用useEffect将满足我的需要。

import React, {useState, useEffect} from "react";
import "./styles.css";
import Select from "react-select";

export default function App() {
  const [items, setItems] = useState([]);
  useEffect(() => {
    console.log(items)
  }, [items])

  const options = [
    {value: 1, label: "Item 1"},
    {value: 2, label: "Item 2"},
    {value: 3, label: "Item 3"},
    ]

  function hanldeItemChange(selectedItems) {
    console.log(`selectedItems = ${selectedItems}`);
    var mappedItems = selectedItems.map(item => item.value);
    console.log(`mappedItems = ${mappedItems}`);
    setItems(mappedItems);
    console.log(`items = ${items}`);
  }

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Select
          className="basic-multi-select"
          classNamePrefix="select"
          onChange={hanldeItemChange}
          isMulti
          name="Items"
          options={options}
        />

    </div>
  );
}
jjhzyzn0

jjhzyzn02#

我误解了useState是如何工作的。正如Nijat所建议的,使用useEffect将满足我的需要。
一旦所选值改变,onChange内的代码开始运行,并且当它完成时(或者在某个点由于await而被跳过),react将检查是否存在状态更新,并且如果存在,则仅在那时useState钩子的值被更新,并且这导致新的呈现,其中新的值是可用的,因此新的数据被显示在UI中。

const [example,setExemple] = useState("")
//...
const newValue = "new"
setExample(newValue);
console.log(example)// output "" and this is normal

因此,如果您希望在代码执行完毕之前使用example的新值,则只需使用newValue即可进行API调用或更新另一个状态(在您的情况下是mappedItems)。这比触发useEffect来这样做更好,因为它将仅在下一次呈现时运行,并且如果它内部的代码正在更新状态,则这将导致可以避免的另一个渲染。
试着更好地理解:

<div className="App">
  {console.log("this is a new render and these are my items : ",items)}
  //...
</div>

你将在第一次渲染中看到空数组,然后在第二次渲染中看到新数组(就像你在useEffect中看到的输出一样),因为组件因为状态更新而重新渲染。

相关问题