【问题标题】:React + Redux - Component doesn't update after state changeReact + Redux - 状态更改后组件不更新
【发布时间】:2019-12-29 21:20:03
【问题描述】:

您好,我有一个 React+Redux 应用程序。它由标题和登录表单组成。用户成功登录后,我希望在标题中显示注销按钮。但是现在似乎反应在登录操作发生之前呈现标题,除非我刷新页面注销按钮不显示。

我的登录表单

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

可能是什么原因?

【问题讨论】:

    标签: reactjs redux


    【解决方案1】:

    constructor 只执行一次,所以当你设置isLogged

    this.state = {
       isLogged: this.props.isLogged,
       showText: true
    };
    

    isLogged 在收到下一个 props 时不会更改。

    这里有两种方法。

    1. 最简单的一种是,直接使用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>
    }
    
    1. 另一种方法是在您使用componentDidUpdate 接收新道具时手动更新状态
    componentDidUpdate(nextProps){
      if(nextProps.isLogged !== this.props.isLogged){
         this.setState({isLogged: this.props.isLogged})
      }
    }
    

    【讨论】:

    • 抓得好馄饨! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多