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

时间:2016-06-23 23:53:19

标签: javascript reactjs

我试图针对某些权限对子组件执行授权。我使用ref回调来访问节点,其中我可以检查权限。根据这些权限,我想卸载组件。

在回调中,我尝试使用ReactDOM.findDOMNode()然后ReactDOM.unmountComponentAtNode()删除它。后者保持返回false,尽管findDomNode似乎正确地选择了DOM元素。

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

    ...

如何使用ReactDOM.unmountComponentAtNode()有效删除我的组件?

1 个答案:

答案 0 :(得分:1)

我认为你不想只是为了检查权限然后卸载它而挂载你的节点。您应该在渲染之前检查权限。它不仅更安全,而且更简单。

如果用户已获得授权,则您将呈现该组件。如果用户未获得授权,则会呈现其他内容。

有点像这样:

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

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

如果您发现自己手动操作DOM,请退后一步,确保没有更多“Reacty”方法来执行此操作。

更新:

如果你想要一个包装器组件,你可以根据权限放置应该或不应该渲染其子节点的东西,也许你会这样做:

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

现在你可以使用这个包装器:

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