嗨,我有一个React + Redux应用程序。它由标题和登录表单组成。用户成功登录后,我希望注销按钮显示在标题中。但是现在看来,在登录操作发生之前,除非我未显示刷新页面注销按钮,否则react渲染头会出现。
我的登录表格
class LoginForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit = (e, {setFieldError, setSubmitting}) => {
const {username, password} = e;
if (username && password) {
loginService
.login(username, password)
.then(
success => {
const data = success.data;
if (success.status === 200 && data.success === true) {
return {...data.user, password: password};
} else if (success.status === 400) {
window.location.reload();
}
const error = (!data.success && "Wrong credentials") || success.statusText;
return Promise.reject(error);
}
)
.then(
auth => {
this.props.login(auth)
},
error => {
if (error.response.status === 400) {
setFieldError("username", "Zły login lub hasło");
setFieldError("password", " ");
setSubmitting(false);
}
}
)
}
};
render() {
return (
<Formik ...
)
}
function mapState(state) {
const {session} = state;
return {session}
}
const connectedLoginForm = connect(mapState, {login: loginActions.login})(LoginForm);
export {connectedLoginForm as LoginForm};
在用户按下登录按钮后调度的我的登录操作
export const loginActions = {
login
};
function login(data) {
const session = {
id: data.id,
username: data.email,
password: data.password
};
loginService.saveSessionData(session);
return dispatch => {
dispatch({type: loginConstants.LOGGED_IN, payload: session});
history.push('/');
}
}
我的登录减少器
const session = loginService.getSessionData();
const initialState = session ? {session} : {};
export function login(state = initialState, action) {
if (action.type === loginConstants.LOGGED_IN) {
return {
session: action.payload
};
} else {
return state
}
}
我的标题类显示不正确
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {
isLogged: this.props.isLogged,
showText: true
};
this.updatePredicate = this.updatePredicate.bind(this);
};
componentDidMount() {
this.updatePredicate();
window.addEventListener("resize", this.updatePredicate);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updatePredicate);
}
updatePredicate() {
this.setState({showText: window.innerWidth > 319});
}
render() {
return (
<MDBNavbar color="white" light expand="md" className={'mt-0'} style={{marginTop: "0px"}} fixed={'top'}>
<MDBNavbarBrand href={'/'}>
<img alt="Logo" src={logo} width="30" height="30" className="d-inline-block align-top"/>
<strong id="app-name">
{AppName}
</strong>
</MDBNavbarBrand>
{this.state.isLogged &&
<MDBNavbarNav right>
<MDBNavItem>
<MDBNavLink to="/logout">
<MDBIcon icon="sign-out-alt"/>
{this.state.showText && <span>Wyloguj się</span>}
</MDBNavLink>
</MDBNavItem>
</MDBNavbarNav>
}
</MDBNavbar>
);
}
}
function mapState(state) {
const {session} = state.login;
return {isLogged: !(typeof session === 'undefined')}
}
const connectedHeader = connect(mapState)(Header);
export {connectedHeader as Header};
可能是什么原因?
答案 0 :(得分:2)
constructor
仅执行一次,因此,当您设置isLogged
时,
this.state = {
isLogged: this.props.isLogged,
showText: true
};
isLogged
在收到下一个道具时不会改变。
您在这里有两种方法。
this.props.isLogged
来满足您的条件,{this.props.isLogged &&
<MDBNavbarNav right>
<MDBNavItem>
<MDBNavLink to="/logout">
<MDBIcon icon="sign-out-alt"/>
{this.state.showText && <span>Wyloguj się</span>}
</MDBNavLink>
</MDBNavItem>
</MDBNavbarNav>
}
componentDidUpdate
接收新道具时手动更新状态componentDidUpdate(nextProps){
if(nextProps.isLogged !== this.props.isLogged){
this.setState({isLogged: this.props.isLogged})
}
}