最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React - sending down ref as a prop not working - Stack Overflow

programmeradmin5浏览0评论

I am using a react-mui library in my project where I would like to implement a MenuList ponent, found under MenuList position here. In my application though I am sending a ref as prop down to a child ponent where I have a menu. You can see the codesandbox example here. When I send a ref and a setRef method as props from a parent ponent like this:

state = {
    open: false,
    ref: React.createRef()
  };

  setRef = element => {
    this.setState({ ref: element });
  };

  handleToggle = () => {
    this.setState(state => ({ open: !state.open }));
  };

  handleClose = () => {
    this.setState({ open: false });
  };

  render() {
    return (
      <MenuListComposition
        setRef={this.setRef}
        handleToggle={this.handleToggle}
        handleClose={this.handleClose}
        open={this.state.open}
        ref={this.state.ref}
      />
    );
  }

To a child ponent that has a menu button:

    <MenuButton
      className={classes.button}
      handleToggle={handleToggle}
      setRef={setRef}
      open={open}
      ref={ref}
   />

Then the Popper ponent which has a menu list opens at a wrong place, which you can see in the codesanbox example if you click on the TOGGLE MENU GROW button.

      <Popper open={open} anchorEl={ref} transition disablePortal>
          {({ TransitionProps, placement }) => (
            <Grow
              {...TransitionProps}
              id="menu-list-grow"
              style={{
                transformOrigin:
                  placement === "bottom" ? "center top" : "center bottom"
              }}
            >
              <Paper>
                <ClickAwayListener onClickAway={handleClose}>
                  <MenuList>
                    <MenuItem onClick={handleClose}>Profile</MenuItem>
                    <MenuItem onClick={handleClose}>My account</MenuItem>
                    <MenuItem onClick={handleClose}>Logout</MenuItem>
                  </MenuList>
                </ClickAwayListener>
              </Paper>
            </Grow>
          )}
        </Popper>

What am I doing wrong and how to fix this, or how can I use ref in a stateless ponent where I would avoid sending down ref as a prop?

I am using a react-mui library in my project where I would like to implement a MenuList ponent, found under MenuList position here. In my application though I am sending a ref as prop down to a child ponent where I have a menu. You can see the codesandbox example here. When I send a ref and a setRef method as props from a parent ponent like this:

state = {
    open: false,
    ref: React.createRef()
  };

  setRef = element => {
    this.setState({ ref: element });
  };

  handleToggle = () => {
    this.setState(state => ({ open: !state.open }));
  };

  handleClose = () => {
    this.setState({ open: false });
  };

  render() {
    return (
      <MenuListComposition
        setRef={this.setRef}
        handleToggle={this.handleToggle}
        handleClose={this.handleClose}
        open={this.state.open}
        ref={this.state.ref}
      />
    );
  }

To a child ponent that has a menu button:

    <MenuButton
      className={classes.button}
      handleToggle={handleToggle}
      setRef={setRef}
      open={open}
      ref={ref}
   />

Then the Popper ponent which has a menu list opens at a wrong place, which you can see in the codesanbox example if you click on the TOGGLE MENU GROW button.

      <Popper open={open} anchorEl={ref} transition disablePortal>
          {({ TransitionProps, placement }) => (
            <Grow
              {...TransitionProps}
              id="menu-list-grow"
              style={{
                transformOrigin:
                  placement === "bottom" ? "center top" : "center bottom"
              }}
            >
              <Paper>
                <ClickAwayListener onClickAway={handleClose}>
                  <MenuList>
                    <MenuItem onClick={handleClose}>Profile</MenuItem>
                    <MenuItem onClick={handleClose}>My account</MenuItem>
                    <MenuItem onClick={handleClose}>Logout</MenuItem>
                  </MenuList>
                </ClickAwayListener>
              </Paper>
            </Grow>
          )}
        </Popper>

What am I doing wrong and how to fix this, or how can I use ref in a stateless ponent where I would avoid sending down ref as a prop?

Share Improve this question edited Jun 2, 2023 at 15:42 NearHuscarl 81.5k22 gold badges318 silver badges280 bronze badges asked Jul 9, 2019 at 7:17 LeffLeff 1,35031 gold badges111 silver badges224 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

ref is a keyword in reactjs. When you use ref as a prop it linked the ponent to the ref object. Rename it to whatever you like on FancyButton ponent and MenuListComposition ponent.

From react documentation.

React supports a special attribute that you can attach to any ponent.

Working example with ref renamed to parentRef in both ponents.

EDIT:

As pointed it out by Vaibhav Shukla, you can use React.forwardRef on both FancyButton and MenuListComposition which is probably the correct way to do this.

Working example

Ref cannot be passed like a prop in React. Refs are monly assigned to an instance property when a ponent is constructed so they can be referenced throughout the ponent. Moreover, When a ref is passed to an element in render, a reference to the node bees accessible at the current attribute of the ref.

React provides method React.forwardRef to pass refs in the ponent hierarchy. This is typically not necessary for most ponents in the application. However, it can be useful for some kinds of ponents, especially in reusable ponent libraries. Read about forwardRef

    const ButtonWrapper = React.forwardRef((props, ref) => (
      <button ref={ref}>
        {props.children}
      </button>
    ));

    // You can now get a ref directly to the DOM button:
    const ref = React.createRef();
    <ButtonWrapper ref={ref}>Click me!</ButtonWrapper>;
发布评论

评论列表(0)

  1. 暂无评论