几周左右我就开始学习一些教程来学习一些React。
现在我试图让Auth使用管理信息中心。 我在仪表板中有一个侧边栏,希望它切换。在我添加Auth之前,这个工作正常。 现在我有一个HOC:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {Route, Redirect} from 'react-router-dom';
export const PrivateRoute = ({component: ComposedComponent, ...rest}) => {
class Authentication extends Component {
// redirect if not authenticated; otherwise, return the component inputted into <PrivateRoute />
handleRender(props) {
if (!this.props.authenticated) {
return <Redirect to={{
pathname: '/login',
}}/>;
} else {
return <ComposedComponent {...props}/>;
}
}
render() {
return (
<Route {...rest} render={this.handleRender.bind(this)}/>
);
}
}
function mapStateToProps(state) {
return {authenticated: state.auth.authenticated};
}
const AuthenticationContainer = connect(mapStateToProps)(Authentication);
return <AuthenticationContainer/>;
};
我的TemplateComponent
import React, {Component} from 'react';
import './Template.css';
class Template extends Component {
constructor(props) {
super(props)
this.state = {toggled: true}
}
toggleMenu = () => {
this.setState({toggled: !this.state.toggled});
};
render() {
const sidebar = `sidebar-toggle ${this.state.toggled ? 'active' : ''}`;
return(
<nav className="navbar navbar-inverse" role="navigation">
<div className="container">
<div className="navbar-header">
<a id="menu-toggle" href="#" className="navbar-toggle" onClick={this.toggleMenu}>
<span className="sr-only">Toggle navigation</span>
<span className="icon-bar"/>
<span className="icon-bar"/>
<span className="icon-bar"/>
</a>
<a className="navbar-brand" href="home.xhtml">
Araido
</a>
</div>
<div id="sidebar-wrapper" className={sidebar} >
<ul className="sidebar-nav">
<li>
<a href="#item1">Item 1</a>
</li>
<li>
<a href="#item2">Item 2</a>
</li>
<li>
<a href="#item3">Item 3</a>
</li>
</ul>
</div>
</div>
</nav>
)
}
}
export default Template;
现在发生的事情是当我的组件使用setState()时它会再次触发构造函数。这使我的侧边栏状态恢复为切换状态。
提前致谢
答案 0 :(得分:0)
HOC被描述为
高阶组件是一个带有组件的函数 返回一个新组件。
来源:Higher-Order Components - React Documentation
您的HOC实例化反应组件而不是仅返回它。我想说更常见的模式是返回一个新组件,而不是立即在HOC中创建新实例。
这可能是一个潜在的问题,但它没有必要,因为它取决于您的HOC如何使用组合组件。
仍然可以尝试更改此行
return <AuthenticationContainer/>;
// which is equal to
return React.createElement(AuthenticationContainer, null);
到
return AuthenticationContainer;
请记住,它可能无法解决您的问题。您只共享了应用程序代码的一小部分,但我确信100%您正在努力解决官方React文档中描述的问题 - Don't Use HOCs Inside the render Method:
[...]重新安装组件会导致该组件的状态 所有的孩子都要迷失。
您必须找到以错误方式使用HOC的位置。查看显示此问题的示例:DEMO。
单击Toggle
按钮并打开控制台,您将看到父组件中的每个setState()
调用都会重新装入FooWithHello
并调用其构造函数。
其他改进#1
避免在渲染方法中创建新函数,而不是在.bind()
中使用render()
:
<Route {...rest} render={this.handleRender.bind(this)}/>
你应该做
this.handleRender = () => {
if (!this.props.authenticated) {
return <Redirect to={{ pathname: '/login' }} />;
}
return <ComposedComponent {...props} />;
};
render() {
return <Route {...rest} render={this.handleRender} />;
}
其他改进#2
当你想使用以前的状态来构建下一个状态时,你应该使用setState()
的回调形式:
toggleMenu = () => {
this.setState(prevState => ({
toggled: !prevState.toggled,
});
};