【问题标题】:ReactJs: Why ref.current returns null when the component is rendered?ReactJs:为什么 ref.current 在渲染组件时返回 null?
【发布时间】:2020-12-08 15:04:50
【问题描述】:

我在购物车中有一个按钮,我想在购物车打开时给它一个动画。为了定位它,我使用了 useRef 并尝试在控制台中登录结果:

const checkoutBtnRef = useRef("null");

    useEffect(() => {
        console.log(checkoutBtnRef.current);
    }, [cartOpen]);

问题是当我打开购物车时 current 为空,只有在我关闭购物车时才返回实际​​按钮,我希望它是相反的。 有什么想法吗?

完整的组件代码

export default function TopNav() {
    const classes = useStyles();
    const [cartOpen, setCartOpen] = useState(false);
    const checkoutBtnRef = useRef("null");

    useEffect(() => {
        console.log(checkoutBtnRef.current);
    }, [cartOpen]);

    return (
        <>
            <Container maxWidth="xl">
                <div className={classes.root}>
                    <CardMedia
                        image="https://www.example.com"
                        className={classes.media}
                    />
                    <SearchBar placeholder="Search" className={classes.searchBar} />
                    <div className={classes.iconsContainer}>
                        <PersonIcon className={classes.icon} />
                        <FavoriteBorderIcon className={classes.icon} />
                        <Badge
                            invisible={false}
                            variant="dot"
                            color="error"
                            onClick={() => setCartOpen(true)}
                        >
                            <ShoppingBasketIcon className={classes.icon} />
                        </Badge>
                    </div>
                </div>
            </Container>
            <Drawer
                classes={{
                    paper: classes.cart,
                }}
                anchor="right"
                open={cartOpen}
                transitionDuration={{ enter: 500, exit: 200 }}
                onClose={() => setCartOpen(false)}
            >
                <div className={classes.topCartContent}>
                    <Typography variant="h5">Cart</Typography>
                    <CloseIcon
                        className={classes.closeIcon}
                        onClick={() => setCartOpen(false)}
                    />
                </div>
                <Divider />
                <List>
                    <CartItem />
                </List>
                <Button
                    classes={{
                        root: classes.checkoutBtn,
                    }}
                    variant="outlined"
                    onClick={() => setCartOpen(false)}
                    ref={checkoutBtnRef}
                >
                    checkout
                </Button>
            </Drawer>
        </>
    );
}

【问题讨论】:

  • 请提供完整的组件代码。
  • @b3hr4d 我发布了完整组件的代码!如果您需要更多详细信息,我将非常乐意提供!

标签: reactjs react-hooks use-ref


【解决方案1】:

编辑: 你的抽屉有延迟,你的按钮还没有呈现,所以你看不到 cartOpen 更改事件上的按钮......

所以使用它来存储和调用你的函数而不是 useEffect。

 const checkoutBtnRef = (ref) => {
   console.log(ref);
   if (ref){
      // do ur staff here
   }
 };

如果你需要useEffect,你可以这样做:

  const [btnRef, setBtnRef] = useState(null);

  const checkoutBtnRef = (ref) => {
    if (ref) setBtnRef(ref);
  };

  useEffect(() => {
    console.log(btnRef);
  }, [btnRef]);

旧答案:

const App = ()=>{
  const [cart,setCart]= React.useState(false);
  const [btnRef, setBtnRef] = React.useState(null);

  const checkoutBtnRef = (ref) => {
    if (ref) setBtnRef(ref);
    else setBtnRef(null)
  };

  React.useEffect(() => {
    console.log(btnRef);
  }, [btnRef]);
  
  const cartHandler = () => {
    setTimeout(()=>{
       setCart((prev) => !prev)
    },1000);
  };
 return (
  <React.Fragment>
    <button onClick={cartHandler}>
     Cart
    </button>
    {cart && <button ref={checkoutBtnRef}>Check Out</button>}
   </React.Fragment>
 )
}

ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

【讨论】:

  • 感谢您的回答!我已经尝试过这种方式并且它完全有意义,但由于某种原因它在我的代码中不起作用。我发布了完整的组件代码,也许你会在我做之前找到问题所在:D
  • 我现在明白了这个问题,但我不明白你的解决方案,你能重构你给我的第一个解决方案吗?我对 React 还很陌生,现在我很困惑
  • 现在可以使用了!我只需要了解你做了什么以及你是如何做到的!非常感谢您的耐心等待!
  • @Zakaria 欢迎您,我喜欢帮助别人。
  • 这是因为 ref props 在 react 中的工作方式,例如 mouseEvent 背后有逻辑。阅读更多信息:reactjs.org/docs/refs-and-the-dom.html
猜你喜欢
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 2016-08-31
  • 1970-01-01
  • 2015-07-29
  • 2018-07-20
相关资源
最近更新 更多