簡體   English   中英

React UseState 沒有立即更新

[英]React UseState not updating immediately

我正在嘗試構建一個反應登陸頁面,以顯示基於 props.products 的不同屏幕。 如果 API 呼叫響應中存在產品,它將更新全局 state 產品並將產品從 null 更新為數組。 我在這里面臨的問題是,即使 state 已更新(我已經檢查過 Redux Dev Tools),頁面也沒有顯示正確的屏幕。 嘗試加載屏幕類型 3 時會出現問題。

function LandingPage(props) {
  const [eligibleProducts, setEligibleProducts] = useState([]);
  const [screenType, setScreenType] = useState();
  const [url, setUrl] = useState("");
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(false);
  const [isActive, setisActive] = useState(false);

  const { pocBusinessEmail, pocBusinessName } = props;

  useEffect(() => {
    handleEligibleProducts();
  }, []);

  useEffect(() => {
    console.log('count')
    if(props.products && (props.products.filter((product) => product.productStatus === 2).length > 0)){
      console.log("init")
      setisActive(true)
    }
  }, [props.products]);

  useEffect(() => {}, [props.eligibleProducts]);
  

  const handleEligibleProducts = async () => {
    setLoading(true);
    let data = {
      userType: 102,
    };
    data["email"] = window.localStorage.getItem("email");

    try {
      
      const res = await props.getEligibleProducts(data);
      const { statusCode, msgText, productList, Url } = res.data.responsePayload;
      let allEligibilityFlagZero = false;
      let noidforsome = false;
      if (Url.length != "") {
        setUrl(new URL(Url));
      }
     if(statusCode === 200){
          let data = {};
          data["employeeId"] = props.employeeId;
          data["products"] = null;
          await props.employeeProduct(data);
      } 

      if (productList) {
        setEligibleProducts(productList.map((product) => ({ ...product, selected: false })));
        allEligibilityFlagZero = productList.length && productList.every((product) => product.eligibilityFlag === 0);
       // noArcIdForSomeProduct = productList.length && productList.some((product) => !(product && (product.arcId || product.arcId !== null)));
      //  if(props.products){
      //     if((props.products.filter((product) => product.productStatus === 2).length > 0)){
      //       setisActive(true)
      //     }
      //   }
      

      
        }

      if (statusCode !== 200) {
        setScreenType(4);
        setMessage(msgText);
      } else if (!(productList && productList.length !== 0) || allEligibilityFlagZero) {
        setScreenType(1);
      } else if (!isActive) {
        setScreenType(2);
      } else {
        setScreenType(3);
      }
      setLoading(false);
      
    } catch (error) {
      setLoading(false);
      console.log("big error: " + error);
    }
  };
  let navigate = useNavigate();
  const routeChange = (direction) => {
    let path = direction;
    navigate(path);
  };

  const getProperScreen = () => {
    switch (screenType) {
      case 1:
        return <ScreenOne eligibleProducts={eligibleProducts} />;

      case 2:
        return <ScreenTwo eligibleProducts={eligibleProducts} handleSelectProduct={handleSelectProduct} selectUnSelectAllProduct={selectUnSelectAllProduct} />;

      case 3:
        return <ScreenThree eligibleProducts={eligibleProducts} handleSelectProduct={handleSelectProduct} selectUnSelectAllProduct={selectUnSelectAllProduct} products= {props.products} />;

      case 4:
        return <ErrorScreen message={message} />;
      
      default: 
        return <ScreenOne eligibleProducts={eligibleProducts} />;
    }
  };

  if (loading) return <Loader />;

  return (
    <>
      <Container maxWidth={false}>
        <Grid container sx={{ justifyContent: "space-between", p: "1rem 2rem" }}>
          <Grid item>
            <Box>
              <Header registrationBool={true} loggedInBool={true} pocBusinessEmail={pocBusinessEmail} pocBusinessName={pocBusinessName} />
            </Box>
          </Grid>
        </Grid>
      </Container>
      {getProperScreen()}
      {<FooterButtonContainer title="Apply Now" handleApplyNow={handleApplyNow} eligibleProducts={eligibleProducts} />}
      <Footer />
    </>
  );
}

export default LandingPage;

我看到的唯一問題是handleEligibleProducts依賴於isActiveprops但調用它的效果掛鈎沒有依賴性。

最好不要在效果掛鈎中調用組件內定義的函數,因為依賴關系圖會變得混亂。 相反,在效果掛鈎本身中定義 function 並確保列出所有依賴項。

const { products, getEligibleProducts, employeeId, employeeProduct } = props;

useEffect(() => {
  const handleEligibleProducts = async () => {
    // ...
  };

  handleEligibleProducts();
}, [
  isActive,
  getEligibleProducts,
  products,
  getEligibleProducts,
  employeeId,
  employeeProduct,
]);

編輯 cranky-satoshi-se5pws

正如F.Müller提到的,理想情況下,您應該使用能指出這些問題的 linter。

暫無
暫無

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

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