反应-发送ref作为道具不起作用

时间:2019-07-09 07:17:02

标签: javascript reactjs react-material react-ref

我在我的项目中使用一个react-mui库,我想在该库中实现一个MenuList组件,该组件位于MenuList组成here下。在我的应用程序中,虽然我将ref作为prop发送到child component,其中我有menu。您可以看到codeandbox示例here。 当我从这样的父组件中以ref的形式发送setRefprops方法时:

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}
      />
    );
  }

对于具有菜单按钮的子组件:

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

然后,具有菜单列表的Popper组件会在错误的位置打开,如果您单击TOGGLE MENU GROW button,则会在codesanbox示例中看到。

      <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>

我在做什么错了,如何解决这个问题,或者如何在ref组件中使用stateless,以避免避免以ref的形式发送prop

2 个答案:

答案 0 :(得分:1)

ref是reactjs中的关键字。当您使用ref作为道具时,它将组件链接到ref对象。将其重命名为FancyButton组件和MenuListComposition组件上的任意名称。

来自react documentation.

  

React支持一个特殊属性,您可以将其附加到任何组件上。

Working example,两个组件中的ref均重命名为parentRef。

编辑:

正如Vaibhav Shukla指出的那样,您可以在React.forwardRefFancyButton上同时使用MenuListComposition,这可能是正确的方法。

Working example

答案 1 :(得分:1)

Ref不能像React中的prop一样传递。构造组件时,通常将引用分配给实例属性,以便可以在整个组件中对其进行引用。此外,当将ref传递到渲染中的元素时,可以在ref的当前属性处访问对节点的引用。

React提供方法 React.forwardRef 以在组件层次结构中传递引用。对于应用程序中的大多数组件,通常不需要这样做。但是,它对于某些类型的组件很有用,尤其是在可重用的组件库中。 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>;