状态 JS 对象在 setState 上不持久

State JS object not persistent upon setState

我的状态是这样的。

let coinlist = {
    BTC:0,
    ETH:0,
    USDT:0,
    XRP:0,
    ADA:0,
    SOL:0,
    AVAX:0,
    DOT:0,
    DOGE:0,
    UST:0,
    SHIB:0,
    MATIC:0,
    WBTC:0,
    CRO:0,
    DAI:0,
    LTC:0,
    ATOM:0,
    LINK:0,
    UNI:0,
    BCH:0,
    XLM:0
}
  const [currencies, setCurrencies] = useState(coinlist);

我正在使用一个 websocket,它提供这些货币的实时价格值。 我的消息看起来像这样。

 useEffect(() => {
  // ...code to set up & configure the websocket

ws.current.onmessage = (e) => {
      let data = JSON.parse(e.data);
      console.log(data)
      if (data.type !== "ticker") {
        return;
      }
      setCurrencies({
          ...currencies,
          [data.product_id.replace("-USD","")]:data.price
      })
    };
  }, []);

现在,在从 ws 收到任何货币的每个新价格后,setState 仅更新特定货币,即这些值在 setStates 中不是持久的。 console.log 看起来像这样。

ADA: 0
ATOM: 0
AVAX: 0
BCH: 0
BTC: 0
CRO: 0
DAI: 0
DOGE: 0
DOT: 0
ETH: 0
LINK: 0
LTC: "125.07"
MATIC: 0
SHIB: 0
SOL: 0
UNI: 0
USDT: 0
UST: 0
WBTC: 0
XLM: 0
XRP: 0

下一条消息如下所示。

ADA: 0
ATOM: 0
AVAX: 0
BCH: 0
BTC: "43935.89"
CRO: 0
DAI: 0
DOGE: 0
DOT: 0
ETH: 0
LINK: 0
LTC: 0
MATIC: 0
SHIB: 0
SOL: 0
UNI: 0
USDT: 0
UST: 0
WBTC: 0
XLM: 0
XRP: 0

我期待的是这样的。

BTC: "43935.89"
SOL: "10.56"
UNI: "277"
USDT: "25"
UST: "105"
WBTC: "200"
XLM: "100.23"
XRP: "0.5"

我是否正确使用了 setCurrencies?

问题是 currencies 状态下的过时关闭。使用功能状态更新从之前的状态正确更新,而不是在回调范围内关闭的初始状态。

示例:

useEffect(() => {
  // ...code to set up & configure the websocket

  ws.current.onmessage = (e) => {
    const data = JSON.parse(e.data);
    console.log(data);

    if (data.type !== "ticker") {
      return;
    }

    setCurrencies(currencies => ({ // <-- previous state
      ...currencies,               // <-- shallow copy
      [data.product_id.replace("-USD","")]: data.price
    }));
  };

  // Don't forget code to clean up socket connections/subscriptions!!
}, []);