单击一次基于单个 websocket 流设置两个状态变量

Set two state variables based on a single websocket stream on a single click

该应用正在传输价格数据。我想单击一个按钮,该按钮在单击按钮时打印价格(状态变量 1,guess),然后 5 秒后再次打印价格(actual,状态变量 2)

price 是来自数据流的状态变量

不幸的是,guess 的值始终等于 actual,即使 price 已更改。

function App() {
  const [price, setPrice] = useState(null);
  const [guess, setGuess] = useState(null);
  const [actual, setActual] = useState(null);
  useEffect(() => {
    const ws = new WebSocket("wss://stream.binance.com:9443/ws/btcusdt@trade");
    ws.onmessage = (event) => {
      let stockObject = JSON.parse(event.data);
      let price = parseFloat(stockObject.p).toFixed(2);
      setPrice(price);
    };
  }, []);

  const sleep = (milliseconds) => {
    return new Promise((resolve) => setTimeout(resolve, milliseconds));
  };

  const makeAGuess = async (price) => {
    setGuess(price);
    await sleep(5000); //wait 5 seconds
  };
  const getActual = async (price) => {
    await sleep(5000); //wait 5 seconds
    setActual(price);
  };

  return (
    <div className="App">
      {price && <h2>{price}</h2>}
      {guess && <h2>{guess}</h2>}
      {actual && <h2>{actual}</h2>}
      <button onClick={() => makeAGuess(price).then(getActual(price))}>
        Click me
      </button>
    </div>
  );```

您可以使用 useRef 挂钩获取 state 的当前值。 用当前值更新。在这种情况下,您必须更新 .current 属性 的 useRef 变量的值是 priceRef.current.

function App() {
    const [price, setPrice] = useState(null);
    const [guess, setGuess] = useState(null);
    const [actual, setActual] = useState(null);
    const priceRef = useRef(price);
    priceRef.current = price;
    
    useEffect(() => {
      const ws = new WebSocket("wss://stream.binance.com:9443/ws/btcusdt@trade");
      ws.onmessage = (event) => {
        let stockObject = JSON.parse(event.data);
        let price = parseFloat(stockObject.p).toFixed(2);
        setPrice(price);
      };
    }, []);
  
    const sleep = (milliseconds) => {
      return new Promise((resolve) => setTimeout(resolve, milliseconds));
    };
  
    const makeAGuess = async () => {
      setGuess(price);
      await sleep(5000); //wait 5 seconds
    };
    const getActual = async () => {
      await sleep(5000); //wait 5 seconds
      setActual(priceRef.current);
    };
  
    return (
      <div className="App">
        {price && <h2>{price}</h2>}
        {guess && <h2>{guess}</h2>}
        {actual && <h2>{actual}</h2>}
        <button onClick={() => { makeAGuess(); getActual() }}>
          Click me
        </button>
      </div>
    );
export default Sidebar;