简体   繁体   English

无法卸载React组件,从父组件返回false

[英]Can't unmount React component, returning false from parent component

I'm trying to perform authorization on a child component against certain permissions. 我正在尝试针对某些权限对子组件执行授权。 I'm using ref callback to get access to the Node, wherein I can check permissions. 我正在使用ref回调来获取对Node的访问权限,在其中可以检查权限。 Depending on these permissions, I would like to unmount the component. 根据这些权限,我想卸载该组件。

Within the callback, I'm trying to use ReactDOM.findDOMNode() and then ReactDOM.unmountComponentAtNode() to remove it. 在回调,我试图用ReactDOM.findDOMNode()然后ReactDOM.unmountComponentAtNode()将其删除。 The latter keeps returning false, although findDomNode appears to properly be selecting the DOM element. 尽管findDomNode似乎正确选择了DOM元素,但后者始终返回false。

class Auth extends React.Component {

    ...

    checkPermissions(component) {
        const domNode = ReactDOM.findDOMNode(component); // => <p>...</p>

        if (domNode) {
            let wasUnmounted = ReactDOM.unmountComponentAtNode(domNode);
            console.log('was unmounted', wasUnmounted); // => false
        }
    }

    render(){
        return (
            <div>
                {this.state.authorized &&
                    <Component ref={(c) => this.checkPermissions(c)} {...this.props} />
                }
            </div>
        )
    }

    ...

How can I use ReactDOM.unmountComponentAtNode() to effectively remove my component? 如何使用ReactDOM.unmountComponentAtNode()有效删除组件?

I don't think you'll want to mount your node just to check permissions and then unmount it. 我不认为您只想检查权限然后再卸载它就不需要安装节点。 You should check permissions before you render. 渲染之前,应检查权限。 Not only is it more secure, but it's also simpler. 它不仅更安全,而且更简单。

If the user is authorized, you render the component. 如果用户被授权,则渲染组件。 If the user is not authorized, you render something else. 如果未授权用户,则渲染其他内容。

So something kind of like this: 所以有点像这样:

render() {
  if (!this.state.authorized) {
    return <PleaseLogIn />;
  }

  return (
    <div>
      <Component {...this.props} />
    </div>
  );
}

If you find yourself manipulating the DOM manually, take a step back and make sure there's not a more "Reacty" way to do it. 如果您发现自己手动操作DOM,请退后一步,确保没有更多的“反应式”方法来执行此操作。

Update: 更新:

If you want a wrapper component that you can put around things that should or shouldn't render its children based on permissions maybe you do something like this: 如果您想要一个包装器组件,可以根据权限放置应该或不应该呈现其子组件的内容,则可以执行以下操作:

// state.userPermissions = ['permission1', 'permission1', 'betaTolerant'];

const AuthWrapper = React.createClass({
  propTypes: {
    userPermissions: React.PropTypes.array.isRequired,
    requiredPermissions: React.PropTypes.array.isRequired,
    children: React.PropTypes.node.isRequired
  },

  isAllowed() {
    const { userPermissions, requiredPermissions } = this.props;
    return requiredPermissions.some((requiredPermission) => {
      return userPermissions.some((userPermission) => {
        // If this ever returns true, isAllowed will return true
        // Meaning: If any of the requiredPermissions match
        // any of the userPermissions
        return requiredPermission === userPermission;
      });
    });
  },

  render {
    if(!this.isAllowed()) return null;
    return this.props.children;
  };
});

const mapStateToProps = (state) => {
  // Only this auth component has access to state
  return {
    userPermissions: state.userPermissions
  };
};

export default connect(
  mapStateToProps,
  null
)(AuthWrapper);

Now you can use this wrapper like: 现在,您可以像下面这样使用该包装器:

// Inside some component
render {
  return (
    <MyApp>
      <NormalFeature />
      <AuthWrapper requiredPermissions=['secretFeature', 'betaTolerant']>
        <SecretFeature />
      </AuthWrapper>
    </MyApp>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM