我试图针对某些权限对子组件执行授权。我使用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()
有效删除我的组件?
答案 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>
);
}