繁体   English   中英

使用Meteor和React无法获得快速的用户注册

[英]Cannot get rif of user registration using Meteor and React

我是Meteor的新手,正在学习。 实际上,我正在为每个注册用户创建一个带有专用控制面板的用户登录,注册页面。

我可以正确注册和登录,但是II有两个不同的问题:

  1. 在创建用户时,我无法将信息保存到配置文件对象,并且似乎根本没有触发onCreateUser方法。
  2. 当用户登录时,我会在“控制面板”页面中获得用户信息,但是如果刷新页面,即使用户仍在登录,我也不会再收到这些信息。

这是代码。

/imports/api/users.js

import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';

if (Meteor.isServer) {
  Meteor.publish('userData', () => {
    return Meteor.users.find({ _id: Meteor.userId() }, {
      fields: { profile: 1 }
    });
  });
}

Accounts.onCreateUser((options, user) => {
  user.profile = options.profile || {};
  user.profile.accountType = options.accountType;

  return user;
});

/imports/ui/Signup.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import Joi from 'joi';
import validation from 'react-validation-mixin';
import strategy from 'joi-validation-strategy';
import classnames from 'classnames';

import history from '../../utils/history';

class Signup extends Component {
  constructor(props) {
    super(props);

    this.validatorTypes = {
      accountType: Joi.string().required().label('Account type'),
      email: Joi.string().email().label('Email'),
      password: Joi.string().required().min(6).label('Password'),
      confirmPassword: Joi.string().required().min(6).valid(Joi.ref('password')).label('Confirm password').options({
        language: {
          any: {
            allowOnly: '!!Passwords do not match'
          }
        }
      })
    };

    this.getValidatorData = this.getValidatorData.bind(this);
    this.renderHelpText = this.renderHelpText.bind(this);
    this.getClasses = this.getClasses.bind(this);
    this.onSubmit = this.onSubmit.bind(this);

    this.state = {
      serverError: ''
    };
  }

  componentWillMount() {
    if (Meteor.userId()) {
      history.replace('/');
    }
  }

  getValidatorData() {
    return {
      accountType: this.refs.accountType.value,
      email: this.refs.email.value,
      password: this.refs.password.value,
      confirmPassword: this.refs.confirmPassword.value
    };
  }

  renderHelpText(message) {
    return (
      <span className='validation-error-message'>{message}</span>
    );
  }

  getClasses(field) {
    return classnames({
      'form-group': true,
      'has-error': !this.props.isValid(field)
    });
  }

  onSubmit(e) {
    e.preventDefault();

    const onValidate = error => {
      if (!error) {
        let accountType = this.refs.accountType.value;
        let email = this.refs.email.value.trim();
        let password = this.refs.password.value.trim();
        let confirmPassword = this.refs.confirmPassword.value.trim();

        Accounts.createUser({ email, password, accountType }, (err) => {
          if (err) {
            this.setState({
              serverError: err.reason
            });
          } else {
            this.setState({
              serverError: ''
            });
            history.replace('/account');
          }
        });
      }
    };

    this.props.validate(onValidate);
  }

  render() {
    return (
      <div className="form-container">
        <h3>Create Account</h3>
        <form onSubmit={this.onSubmit}>
          <div className={this.getClasses('accountType')}>
            <select
              className="form-control"
              name="accountType"
              ref="accountType"
              placeholder="Account type"
              onChange={this.props.handleValidation('accountType')}
            >
              <option value="">Select account type</option>
              <option value="student">Sudent</option>
              <option value="teacher">Teacher</option>
              <option value="guest">Guest</option>
            </select>
            {this.renderHelpText(this.props.getValidationMessages('accountType')[0])}
          </div>
          <div className={this.getClasses('email')}>
            <input
              className="form-control"
              type="text"
              name="email"
              ref="email"
              placeholder="email address"
              onChange={this.props.handleValidation('email')}
            />
            {this.renderHelpText(this.props.getValidationMessages('email')[0])}
          </div>
          <div className={this.getClasses('password')}>
            <input
              className="form-control"
              type="password"
              name="password"
              ref="password"
              placeholder="password"
              onChange={this.props.handleValidation('password')}
            />
            {this.renderHelpText(this.props.getValidationMessages('password')[0])}
          </div>
          <div className={this.getClasses('confirmPassword')}>
            <input
              className="form-control"
              type="password"
              name="confirmPassword"
              ref="confirmPassword"
              placeholder="confirm password"
              onBlur={this.props.handleValidation('confirmPassword')}
            />
            {this.renderHelpText(this.props.getValidationMessages('confirmPassword')[0])}
          </div>
          <button className="btn btn-dark" type="submit">Create</button>
        </form>
        <div className="meta">
          <p>Already have an account? <Link to="/login">Login</Link></p>
        </div>
      </div>
    );
  }
};

export default validation(strategy)(Signup);

当我创建一个新的使用方法我想到的是users.js称为Accounts.onCreateUser被解雇和accountType添加信息资料。 不会的

我还希望始终在控制面板中检索当前登录的用户信息。 这是控制面板组件:

/imports/ui/Account.js

从'react'导入React,{组件}; 从“流星/流星”导入{流星};

从“ ../../utils/history”导入历史记录;

class Account extends Component {
  constructor(props) {
    super(props);

    Meteor.subscribe('userData');

    this.state = {
      user: {}
    }
  }

  componentWillMount() {
    if (!Meteor.userId()) {
      history.replace('/login');
    }
  }

  componentDidMount() {
    console.log(Meteor.userId()); // I can always get this value
    const user = Meteor.users.find({ _id: Meteor.userId() }, {
      fields: { profile: 1 }
    }).fetch();
    console.log(user); // On refresh it is an empty array [].

    this.setState({ user });
  }

  render() {
    return (
      <div>Hello Account</div>
    );
  }
};

export default Account;

我做错了什么?

您的代码有几处错误,但可以轻松解决。

  1. Accounts.onCreateUser是仅服务器功能。 console.log插入函数中只是为了确保它被调用。 如果不是,请确保在main.js import '/imports/api/users.js'

  2. Accounts.createUser在options对象中仅接受4个键: usernameemailpasswordprofile (请参阅docs )。 这就是为什么accountType不传递给onCreateUser 执行Accounts.createUser({ email, password, profile: { accountType } }, ...) 然后在onCreateUser ,在options.profile.accountType下找到accountType

  3. 要订阅数据,您应该使用流星createContainer组件。 请参阅指南 这将解决以下问题:在装入组件时,您的数据尚不可用,并在数据准备好后将其重新呈现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM