TypeError:无法读取null的属性“ first_name”

时间:2019-05-19 13:20:51

标签: node.js reactjs

我在react + node + mysql中有一个登录页面,当我登录到页面时会引发错误-> TypeError:无法读取null的属性“ first_name”。

即使我的令牌是在User.js的第69行使用console.log打印的,并且执行了res.send,但仍然在Profile.js的第37行中给出了错误。

需要一些帮助来解决它。

Profile.js

import jwt_decode from 'jwt-decode'

class Profile extends Component {
    constructor() {
        super()
        console.log('profile class')
        this.setState = {
            first_name: '',
            last_name: '',
            email: ''
        }
    }

    componentDidMount() {
        const token = localStorage.getItem('usertoken')
        const decoded = jwt_decode(token)
        console.log('value ->' + decoded)
        this.setState({
            first_name: decoded.first_name,
            last_name: decoded.last_name,
            email: decoded.email
        })
    }

    render(){
        return(
            <div className="container">
                <div className="jumbotron mt-5">
                    <div className="col-sm-8 mx-auto">
                        <h1 className="text-center">PROFILE</h1>
                    </div>
                    <table className="table col-md-6 mx-auto">
                        <tbody>
                            <tr>
                                <td>First Name</td>
                                <td>{this.state.first_name}</td>
                            </tr>
                            <tr>
                                <td>Last Name</td>
                                <td>{this.state.last_name}</td>
                            </tr>
                            <tr>
                                <td>Email</td>
                                <td>{this.state.email}</td>       
                            </tr>
                        </tbody>
                    </table>
                </div>

            </div>
        )
    }
}

export default Profile

Login.js

import { login } from './UserFunctions'

class Login extends Component {
    constructor() {
        super()
        this.state = {
            email: '',
            password: ''
        }

        this.onChange = this.onChange.bind(this)
        this.onSubmit = this.onSubmit.bind(this)
    }

    onChange(e){
        this.setState({[e.target.name]: [e.target.value]})
    }

    onSubmit(e){
        e.preventDefault()

        const user = {
            email: this.state.email,
            password: this.state.password
        }
        login(user).then(res=> {
            if(res) {
                this.props.history.push(`/profile`)
            }
        })
    }

    render(){
        return(
            <div className="container">
                <div className="row">
                    <div className="col-md-6 mt-5 mx-auto">
                        <form noValidate onSubmit={this.onSubmit}>
                            <h1 className="h3 mb-3 font-weight-normal">Please sign in</h1>
                            <div className="form-group">
                                <label htmlFor="email">Email Address</label>
                                <input type="email"
                                className="form-control"
                                name="email"
                                placeholder="Enter Email"
                                value={this.state.email}
                                onChange={this.onChange}/>
                            </div>
                            <div className="form-group">
                                <label htmlFor="password">Password</label>
                                <input type="password"
                                className="form-control"
                                name="password"
                                placeholder="Enter Password"
                                value={this.state.password}
                                onChange={this.onChange}/>
                            </div>
                            <button type="submit"
                            className="btn btn-lg btn-primary btn-block">
                                Sign in
                            </button>
                        </form>
                    </div>
                </div>
            </div>
        )
    }
}

export default Login

UserFuctions.js

console.log("abc")
export const register = newUser => {
    return axios
    .post('/users/register', {
        first_name: newUser.first_name,
        last_name: newUser.last_name,
        email: newUser.email,
        password: newUser.password
    })
    .then(res => {
        console.log("Registered");
    })
}

export const login = user => {
    return axios
    .post('/users/login', {
        email: user.email,
        password: user.password
    })
    .then(res=>{
        localStorage.setItem('usertoken', res.data)
        return res.data
    })
    .catch(err => {
        console.log(err)
    })
}

**。/ routes / Users.js **

const users = express.Router()
const cors = require('cors')
const jwt = require("jsonwebtoken")
const bcrypt = require('bcrypt')

const User = require("../models/User")
users.use(cors())
process.env.SECRET_KEY = 'secret'

users.post('/register', (req, res) => {
    const today = new Date()

    const userData = {
        first_name: String(req.body.first_name),
        last_name: String(req.body.last_name),
        email: String(req.body.email),
        password: req.body.password,
        created: today
    }
    User.findOne({
        where: {
            email: req.body.email
         }
    })
    .then(user => {
        if(!user){
            bcrypt.hash(String(req.body.password), 10, (err, hash) => {
                userData.password = hash
                console.log('req.body.password -> ' + String(req.body.password))
                console.log('req.body -> '  + req.body)
                console.log('hash -> '    + hash + ' ' + err )
                console.log('keys -> '    + Object.keys(userData))
                console.log('values -> '  + Object.values(userData))
                User.create(userData)
                    .then(user => {
                        console.log('inside!')
                        res.json({status: user.email + ' registered'})
                    })
                    .catch(err => {
                        console.log('in catch!' + err)
                        res.send('error: ' + err)
                    })
            })  
        }   else {
            res.json({error: "User already exists"})
        }
    })
    .catch(err => {
        res.send('error: ' + err)
    })
})

users.post('/login', (req, res) => {
    console.log('login step 22')
    User.findOne({
        where: {
            email: req.body.email
        }
    })
    .then(user => {
        if(user) {
            console.log(req.body.password +  ' >> ' +  user.password)
            if(bcrypt.compareSync(String(req.body.password), user.password)) {
                console.log('bcrypt')
                let token = jwt.sign(user.dataValues, process.env.SECRET_KEY, {
                    expiresIn: 1440
                })
                console.log('token --> ' + token);
                res.send(token)
            }
        } else {
            res.status(400).json({error: 'User does not exist'})
        }
    })
    .catch(err => {
        res.status(400).json({ error: err})
    })
})

module.exports = users

1 个答案:

答案 0 :(得分:0)

您在Profile中的初始状态不正确:

this.setState = {
   first_name: '',
   last_name: '',
   email: ''
}

必须是:

this.state = {
   first_name: '',
   last_name: '',
   email: ''
}

您实际上可以将其移出构造函数:

class Profile extends Component {
  state = {
     first_name: '',
     last_name: '',
     email: ''
  };

  ...
}