React 状态在重新渲染后重置

时间:2021-03-14 00:04:33

标签: javascript reactjs react-hooks react-context react-functional-component

我是 React 的新手,面临更新功能组件状态的问题。

我有一个像下面这样的组件 TinderCards.js,它基本上从上下文提供程序中获取对象列表,并为每个对象创建一个 TinderCard (https://www.npmjs.com/package/react-tinder-card),它应该滑动时更新 count (onSwipe)。

然而,每次刷卡时,count 都会增加到 1,然后不再继续。

例如

<块引用>

初始计数值:0

<块引用>

刷第一张卡 => 计数 = 1

<块引用>

刷第二张卡 => count = 1(应该是 2)

<块引用>

刷第三张卡 => count = 1(应该是 3)

我尝试将 count 值作为组件状态的一部分和名为 ResultsContext.js 的全局上下文的一部分包含在内,但两者都会导致相同的行为。

注意,类 test-btn 的按钮在 onClick 处的行为完全符合我的要求。然而,onSwipe 组件的 TinderCard 没有,即使它们基本上是相同的代码并且让我发疯。

TinderCards.js

import React, { useState, useEffect, useContext } from "react";
import TinderCard from "react-tinder-card";
import StocksContext from "./StocksContext";
import ResultsContext from "./ResultsContext";
import "./Tindercards.css";

function TinderCards(props) {
  // const [count, setCount] = useState(0);
  const { count, setCount } = useContext(ResultsContext);
  const { stocks, setStocks } = useContext(StocksContext);

  return (
    <div>
      <div className="tinderCards__cardContainer">
        <div>
          Count: {count}
          <button className="test-btn" onClick={() => setCount(count + 1)}>Increment</button>
        </div>
        <div className="main__container">
          {stocks.map((stock) => (
            <TinderCard
              onSwipe={() => setCount(count + 1)}
              className="swipe"
              key={stock.name}
              preventSwipe={["up", "down"]}
            >
              <div className="card">
                <div style={{ height: "100%" }}>
                  <img
                    src={stock.url}
                    style={{
                      objectFit: "contain",
                      height: "100%",
                      width: "100%",
                      backgroundColor: "white",
                    }}
                  />
                </div>
              </div>
              <h3 style={{ backgroundColor: "white" }}>${stock.name}</h3>
            </TinderCard>
          ))}
        </div>
      </div>
    </div>
  );
}

export default TinderCards;

感谢您的帮助!非常感谢!

1 个答案:

答案 0 :(得分:0)

count 处理程序中的每个 onSwipe 变量:

() => setCount(count + 1)

是一个闭包,它包含了 count 在它们被渲染时的值 - 即 0。其中一个运行的函数实际上并没有改变 count 变量的值 - 它只是触发父组件的重新渲染。那些其他孩子仍然保留他们的 onSwipe 处理程序,只是将计数设置为 2(比渲染时 count 的值多 1) - 这就是您所看到的。

这里的简单解决方案是将 update function 传递给 setCount,而不是硬编码值:

onSwipe={() => setCount(prevCount => prevCount + 1)}

这将确保始终读取 count 状态的“最新值”,并以 1 递增。