如何在组件中显示减速器的道具

时间:2018-12-09 08:45:41

标签: javascript reactjs

我想表演时遇到问题

const mapStateToProps = state => {
    return {
        loading: state.auth.loading,
        error: state.auth.error,
        userId: state.auth.userId,
        tokenId: state.auth.token
    }
}

这是我的职责

register = (event) => {
    event.preventDefault()
    this.props.onAuth( this.state.email, this.state.password, this.state.isSignup );
    localStorage.setItem('token', this.props.tokenId);
    localStorage.setItem('userId', this.props.userId);
}

第二次点击后,我看到了令牌和用户ID。但是第一次单击后看不到。我需要立即显示什么?

这是我的auth.js简化器

import * as actionTypes from '../actions/actionsTypes';
import { updateObject } from '../utility';

const initialState = {
    token: null,
    userId: null,
    error: null,
    loading: false
};

const authStart = ( state, action ) => {
    return updateObject( state, { error: null, loading: true } );
};

const authSuccess = (state, action) => {
    return updateObject( state, { 
        token: action.idToken,
        userId: action.userId,
        error: null,
        loading: false
     } );
};

const authFail = (state, action) => {
    return updateObject( state, {
        error: action.error,
        loading: false
    });
}

const reducer = ( state = initialState, action ) => {
    switch ( action.type ) {
        case actionTypes.AUTH_START: return authStart(state, action);
        case actionTypes.AUTH_SUCCESS: return authSuccess(state, action);
        case actionTypes.AUTH_FAIL: return authFail(state, action);
        default:
            return state;
    }
};

export default reducer;

但是,第一次单击后,我在渲染函数中获得了令牌。 {this.props.tokenId}

能帮我吗?我想我需要使用异步/等待。但是我不确定。

这是Header.js

import React, { Component } from 'react'
import { connect } from 'react-redux'
import * as actions from '../../store/actions/index'
import PropTypes from 'prop-types'

import './header.css'

class Header extends Component {

    constructor(props) {
        super(props)
        this.state = {
            email: '',
            password: '',
            isSignup: true,
            token: false
        }
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange (evt) {
        this.setState({ [evt.target.name]: evt.target.value });
    }
    switchAuthModeHandler = (event) => {
        event.preventDefault()
        this.setState(prevState => {
            return {
                isSignup: !prevState.isSignup
            }
        })
    }

    register = (event) => {
        event.preventDefault()
        this.props.onAuth( this.state.email, this.state.password, this.state.isSignup );
        localStorage.setItem('token', this.props.tokenId);
        localStorage.setItem('userId', this.props.userId);
    }
    render() {
      let regBtn = ''
      if (this.state.isSignup) {
        regBtn = 'Register'
      }
      else {
        regBtn = 'Login'
      }

    let login = null
    if(!this.props.tokenId) {
        login = (
            <div className="login">
                <form onSubmit={this.register}>
                    <input type="email" placeholder="email" name="email" onChange={this.handleChange} />
                    <input type="password" placeholder="password" name="password" onChange={this.handleChange} />
                    <button>{regBtn}</button>
                </form>
                <div onClick={this.switchAuthModeHandler} className="switch">Switch to {this.state.isSignup ? 'Login' : 'Register'}</div>
            </div>
        )
    }
    else {
        login = (
            <div>
                <p>Hello: {this.props.userId}</p>
                <button>Logout</button>
            </div>
        )
    }
    if(this.props.loading) {
        login = <div>Loading...</div>
    }
    return (
      <div>
        <div className="header-inner">
            {this.props.tokenId}
            {login}
          <img src="http://civcic.com/assets/images/header-bg.jpg" alt="img" />
            <div className="header-content">
            <h2>React.JS DEVELOPER</h2>
            <a className="knowmore-btn" href="https://www.upwork.com/freelancers/~01f507600be26cc2a3" rel="noopener noreferrer" target="_blank">Upwork profile</a><br />
            <a className="knowmore-btn" href="https://www.linkedin.com/in/boris-civcic-37244378/" rel="noopener noreferrer" target="_blank">Linkedin</a><br />
            <a className="knowmore-btn" href="https://github.com/fixman93" rel="noopener noreferrer" target="_blank">GitHub</a>
          </div>
        </div>
      </div>
    )
  }
}


Header.defaultProps = {
    tokenId: ''
}


Header.propTypes = {
    tokenId: PropTypes.string
}


const mapStateToProps = state => {
    return {
        loading: state.auth.loading,
        error: state.auth.error,
        userId: state.auth.userId,
        tokenId: state.auth.token
    }
}
const mapDispatchToProps = dispatch => {
    return {
        onAuth: ( email, password, isSignup) => dispatch( actions.auth(email, password, isSignup))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Header)

import axios from 'axios';
import * as actionTypes from './actionsTypes';

export const authStart = () => {
    return {
        type: actionTypes.AUTH_START
    }
}

export const authSuccess = (token, userId) => {
    return {
        type: actionTypes.AUTH_SUCCESS,
        idToken: token,
        userId: userId
    }
}

export const authFail = (error) => {
    return {
        type: actionTypes.AUTH_FAIL,
        error: error
    };
};

export const auth = (email, password, isSignup) => {
    return dispatch => {
        dispatch(authStart());
        const authData = {
            email: email,
            password: password,
            fullName: 'Boris Civcic',
            role: 'admin',
            returnSecureToken: true
        };
        let url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=AIzaSyC5nW8-XOJADEvU7Mi7sgmhUNhHfRxXNQI';
        if (!isSignup) {
            url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=AIzaSyC5nW8-XOJADEvU7Mi7sgmhUNhHfRxXNQI';
        }
        axios.post(url, authData)
        .then(response => {
            console.log(response);
            dispatch(authSuccess(response.data.idToken, response.data.localId));
            // dispatch(checkAuthTime(response.data.expiresIn));
        })
        .catch(err => {
            dispatch(authFail(err.response.data.error));
        })
    };
};

这是auth.js操作

这是实用程序

export const updateObject = (oldObject, updatedProperties) => {
    return {
        ...oldObject,
        ...updatedProperties
    };
};

1 个答案:

答案 0 :(得分:0)

在您的register处理程序中,onAuth是一个异步操作,但是您立即填充了 localStorage 。您应该等待onAuth返回,然后设置您的localStorage项目。

首先从您的重击中返回一个承诺(只需在axios之前添加return即可)

...
return axios.post(url, authData)
  .then(response => {
    console.log(response);
    dispatch(authSuccess(response.data.idToken, response.data.localId));
    // dispatch(checkAuthTime(response.data.expiresIn));
  })
  .catch(err => {
    dispatch(authFail(err.response.data.error));
  })
...

然后按如下所示设置您的localStorage项:

register = (event) => {
  event.preventDefault();
  this.props.onAuth( this.state.email, this.state.password, this.state.isSignup )
   .then(() => {
     localStorage.setItem('token', this.props.tokenId);
     localStorage.setItem('userId', this.props.userId);
   });
}