当父状态传递给子组件更改时,我无法重新呈现组件。 MapNav 组件包含触发更改当前显示弹出窗口的方法的按钮。我的问题是当有人点击 zaloguj 或 wyloguj 时重新渲染UserPopup按钮,它应该可以工作,但它没有,我不知道什么是错的我也不想要在 isLoggedIn 状态发生变化时触发动画,还有一件事logIn方法正确地改变了状态。 isLoggedIn 状态只是暂时的,我将改为使用商店。我正在尝试编写尽可能多的功能组件,但在某些情况下我不能避免使用状态,我打赌我的代码中存在问题所以我会感谢所有改进提示。
const MapNav = (props) => {
return <div className={'mapNavContainer'}>
<ul className={'navList'}>
<li><a href="#about"><i className={"glyphicon glyphicon-fullscreen"} /></a></li>
<li><a href="#about"><i className={"glyphicon glyphicon-chevron-left"} /></a></li>
<li><a href="#about"><i className={"glyphicon glyphicon-chevron-right"} /></a></li>
<li><a href="#about"><i className={"glyphicon glyphicon-map-marker"} /></a></li>
<li><a href="#" onClick={props.onUserIconClick}><i className={"glyphicon glyphicon-user"} /></a></li>
<li><a href="#" onClick={props.onInfoClick}><i className={"glyphicon glyphicon-info-sign"} /></a></li>
</ul>
</div>
}
const UserPopup = (props) => {
return <div>
{(props.isLoggedIn) ? (
<div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Zalogowany</div>
<div className={"panel-body"}>
<button type='submit' onClick={props.logIn}>wyloguj</button>
</div>
</div>
) : (
<div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Niezalogowany</div>
<div className={"panel-body"}>
<button type='submit' onClick={props.logIn}>Zaloguj</button>
</div>
</div>
)
}
</div>;
};
function Welcome(props) {
return <div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Informacje o Autorze.</div>
<div className={"panel-body"}>
Basic panel example
</div>
</div>;
}
class MapHeader extends React.Component {
constructor(props) {
super(props);
this.state = {
currentPopup: null,
isLoggedIn: false,
username: 'gregorowicz.k@gmail.com',
};
this.onInfoClick = this.onInfoClick.bind(this);
this.onUserIconClick = this.onUserIconClick.bind(this);
this.logIn = this.logIn.bind(this);
}
onInfoClick = (e) => {
e.preventDefault();
this.setPopup(<Welcome />);
}
onUserIconClick = (e) => {
e.preventDefault();
const loginPopup = <UserPopup isLoggedIn={this.state.isLoggedIn} username={this.state.username} logIn={this.logIn} />;
this.setPopup(loginPopup);
}
setPopup = (obj) => {
this.state.currentPopup === null ? this.setState({ currentPopup: obj }) : this.setState({ currentPopup: null });
}
logIn = (e) => {
this.setState({ isLoggedIn: !this.state.isLoggedIn });
}
render() {
return (
<nav className={'header'}>
<div className={'container-fluid'}>
<div className={"navbar-header"}>
<button type="button" className={"navbar-toggle collapsed"} data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span className={"sr-only"}>Toggle navigation</span>
<span className={"icon-bar"} />
<span className={"icon-bar"} />
<span className={"icon-bar"} />
</button>
</div>
<div id={"navbar"} className={'navContainer'}>
{MapNav({onInfoClick:this.onInfoClick, onUserIconClick:this.onUserIconClick})}
{this.state.currentPopup ? this.state.currentPopup : null}
</div>
</div>
</nav>
)
}
}
// Render it
ReactDOM.render(
<MapHeader />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css" />
答案 0 :(得分:0)
我已经解决了。在我的代码中有currentPopup状态存储当前弹出窗口,看到更改后我必须卸载并在isLogggedIn状态改变后再次安装组件,所以我改变了显示当前弹出窗口的方式。而是将整个组件存储在状态中,我只存储提供有关当前组件的信息的简单字符串值。无论如何,谢谢你提示,我肯定会在我的代码中应用它们。
const MapNav = (props) => {
return <div className={'mapNavContainer'}>
<ul className={'navList'}>
<li><a href="#about"><i className={"glyphicon glyphicon-fullscreen"} /></a></li>
<li><a href="#about"><i className={"glyphicon glyphicon-chevron-left"} /></a></li>
<li><a href="#about"><i className={"glyphicon glyphicon-chevron-right"} /></a></li>
<li><a href="#about"><i className={"glyphicon glyphicon-map-marker"} /></a></li>
<li><a href="#" onClick={props.onUserIconClick}><i className={"glyphicon glyphicon-user"} /></a></li>
<li><a href="#" onClick={props.onInfoClick}><i className={"glyphicon glyphicon-info-sign"} /></a></li>
</ul>
</div>
}
const UserPopup = (props) => {
return <div>
{(props.isLoggedIn) ? (
<div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Zalogowany</div>
<div className={"panel-body"}>
<button type='submit' onClick={props.logIn}>wyloguj</button>
</div>
</div>
) : (
<div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Niezalogowany</div>
<div className={"panel-body"}>
<button type='submit' onClick={props.logIn}>Zaloguj</button>
</div>
</div>
)
}
</div>;
};
function Welcome(props) {
return <div className={'navPopups col-sm-3 panel panel-default'}>
<div className={"panel-heading"}>Informacje o Autorze.</div>
<div className={"panel-body"}>
Basic panel example
</div>
</div>;
}
class MapHeader extends React.Component {
constructor(props) {
super(props);
this.state = {
currentPopup: null,
isLoggedIn: null,
};
this.onInfoClick = this.onInfoClick.bind(this);
this.onUserIconClick = this.onUserIconClick.bind(this);
this.logIn = this.logIn.bind(this);
}
onInfoClick = (e) => {
e.preventDefault();
this.setState({ currentPopup: this.state.currentPopup === 'info' ? null : 'info' });
}
onUserIconClick = (e) => {
e.preventDefault();
this.setState({ currentPopup: this.state.currentPopup === 'user_login' ? null : 'user_login' });
}
setPopup = (obj) => {
this.setState({ currentPopup: this.state.currentPopup === 'user_login' ? null : 'user_login' });
}
logIn = (e) => {
this.setState({ isLoggedIn: !this.state.isLoggedIn });
}
render() {
return (
<nav className={'header'}>
<div className={'container-fluid'}>
<div className={"navbar-header"}>
<button type="button" className={"navbar-toggle collapsed"} data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span className={"sr-only"}>Toggle navigation</span>
<span className={"icon-bar"} />
<span className={"icon-bar"} />
<span className={"icon-bar"} />
</button>
</div>
<div id={"navbar"} className={'navContainer'}>
{MapNav({onInfoClick:this.onInfoClick, onUserIconClick:this.onUserIconClick})}
{this.state.currentPopup === 'info' ? <Welcome /> : null}
{this.state.currentPopup === 'user_login' ? (
<UserPopup isLoggedIn={this.state.isLoggedIn} logIn={this.logIn} />
) : null}
</div>
</div>
</nav>
)
}
}
// Render it
ReactDOM.render(
<MapHeader />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css" />