2016-12-20 2 views
1

facebook/goolgeログインボタンを使用して、ユーザーの情報をサーバーに自動的に保存します。今、情報がAPI部分に渡されたようです(少なくとも、試したプログラムを意味します...)。ほとんどの場合、エラーはありませんが、ログインページは空白ですが、まだこの種のエラーメッセージが表示されています。ここでfacebook/google loginボタンを使用してreactyでユーザー情報を保存する方法

bundle.js:72621 Uncaught ReferenceError: FB is not defined 
at FacebookButton.componentDidMount (bundle.js:72621) 
at CallbackQueue.notifyAll (bundle.js:6532) 
at ReactReconcileTransaction.close (bundle.js:16290) 
at ReactReconcileTransaction.closeAll (bundle.js:6893) 
at ReactReconcileTransaction.perform (bundle.js:6840) 
at batchedMountComponentIntoNode (bundle.js:2740) 
at ReactDefaultBatchingStrategyTransaction.perform (bundle.js:6827) 
at Object.batchedUpdates (bundle.js:10864) 
at Object.batchedUpdates (bundle.js:6332) 
at Object._renderNewRootComponent (bundle.js:2934) 

は、自分の行動の一部のコードです:

import { FACEBOOKLOGIN } from "../constants/index"; 
const API_URL = "http://localhost:3000"; 
//FACEBOOKLOGIN 
export function facebookLogin(props){ 
    const request = axios.post(`${API_URL}/users`,{ 
    user: { 
     email:props.email, 
     password:props.password, 
     password_confirmation:props.password 
    } 
    }); 
    return{ 
    type: FACEBOOKLOGIN, 
    payload: request 
    } 
} 

、ここでは私のFacebookのログイン機能は

 import React, { Component, PropTypes }from 'react'; 
import { reduxForm } from 'redux-form'; 
import { facebookLogin } from '../../actions/index'; 
import { FACEBOOKLOGIN } from '../../constants/index'; 


var password = {password: "[email protected]"}; 
function validate(values) { 
    const errors = {} 

    if (!values.password) { 
    values.password = password; 
    } 

    return errors 
} 
class FacebookButton extends React.Component { 

    static contextTypes = { 
    router: PropTypes.object 
    }; 
    constructor(props) { 
     super(props); 

     this.FB = props.fb; 

     this.state = { 
     message: "" 
     }; 
     this.onClick = this.onClick.bind(this); 
    } 

    onClick(props){ 
    this.props.facebookLogin(props) 
    .then(() => { 
     this.context.router.push('/'); 
    }); 
    } 

    componentDidMount() { 
     FB.Event.subscribe('auth.logout', 
     this.onLogout.bind(this)); 
     FB.Event.subscribe('auth.statusChange', 
     this.onStatusChange.bind(this)); 
    } 

    onStatusChange(response) { 
     console.log(response); 
     var self = this; 

     if(response.status === "connected") { 
     FB.api('/me', { locale: 'tr_TR', fields: 'name, email,birthday, hometown,education,gender,website,work' }, 
     function(response) { 
      console.log(response.email); 
      console.log(response.name); 
      console.log(response.gender); 
      console.log(response.birthday); 
      console.log(response.hometown); 
      console.log(response.education); 
      console.log(response.website); 
      console.log(response.work); 
      var message; 
      self.setState({ 
       message: response.email 
      }); 
     }) 
     } 
    } 

    onLogout(response) { 
     this.setState({ 
     message: "" 
     }); 
    } 

    render() { 
    const { fields: { email, password }, handleClick, submitting } = this.props 
     return (
     <div> 
     <div className= 
     "fb-login-button" 
     data-max-rows="1" 
     data-size="medium" 
     data-show-faces="true" 
     data-auto-logout-link="true" 
     onclick={this.onClick}></div> 
      <div>{this.state.message}</div> 
     </div> 
    ); 
    } 
}; 

export default reduxForm({ 
    form: 'FacebookButton', 
    fields: ['email','password'], 
    validate 
},null,{facebookLogin})(FacebookButton) 

であり、ここで私は私のFacebookのボタンをレンダリング私のログインフォームです

import React, { Component, PropTypes } from 'react'; 
import { reduxForm } from 'redux-form'; 
import { loginUser } from '../../actions/index'; 
import { Link } from 'react-router'; 
import googleLogin from './google_login.js'; 
import FacebookButton from './facebook_login.js'; 



function validate(values) { 
    const errors = {} 

    if (!values.email) { 
    errors.email = 'Required' 
    } else if (!/^(([^<>()\[\]\\.,;:\[email protected]"]+(\.[^<>()\[\]\\.,;:\[email protected]"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(values.email)) { 
    errors.email = 'Please enter a valid email address' 
    } 

    if (!values.password) { 
    errors.password = 'Required' 
    } 

    return errors 
} 



class LoginForm extends Component { 
    static contextTypes = { 
    router: PropTypes.object 
    }; 



    onSignIn(googleUser) { 
    var profile = googleUser.getBasicProfile(); 
    console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead 
    console.log('Name: ' + profile.getName()); 
    console.log('Image URL: ' + profile.getImageUrl()); 
    console.log('Email: ' + profile.getEmail()); 
    } 

    signOut() { 
     var auth2 = gapi.auth2.getAuthInstance(); 
     auth2.signOut().then(function() { 
     console.log('User signed out.'); 
     }); 
    } 

    onSubmit(props){ 
    this.props.loginUser(props) 
    .then(() => { 
     this.context.router.push('/'); 
    }); 
    } 

    render() { 
    const { fields: { email, password }, handleSubmit, submitting } = this.props 
    return (
     <div> 
     <form onSubmit={handleSubmit(this.props.loginUser)}> 
      <div className={`form-group ${email.touched && email.invalid ? 'has-danger' : ''}`}> 
      <label>E-mail</label> 
      <div> 
      {/* {email.touched && email.error && <div className={s.textError}>{email.error}</div>} */} 
       <input type="email" className="form-control" {...email}/> 
       <div className="email-help-login"> 
       {email.touched ? email.error : ''} 
       </div> 
      </div> 

      </div> 
      <div className={`form-group ${password.touched && password.invalid ? 'has-danger' : ''}`}> 
      <label>Password</label> 
      <div> 
      {/* {password.touched && password.error && <div className={s.textError}>{password.error}</div>} */} 
       <input type="password" className="form-control" {...password}/> 
       <div className="password-help-login"> 
       {password.touched ? password.error : ''} 
       </div> 
      </div> 
      </div> 
      <div> 
      <button type="submit" className="btn btn-primary"> 
       Login 
      </button> 
      </div> 
      <div> 
      <Link to="/" className="btn btn-danger">Cancel</Link> 
      </div> 


     </form> 
     <FacebookButton fb={FB} /> 



     <googleLogin/> 
     <a href="#" onclick="this.signOut();">Sign out</a> 


     </div> 

    ) 
    } 
} 


export default reduxForm({ 
    form: 'LoginForm', 
    fields: ['email','password'], 
    validate 
},null,{loginUser})(LoginForm) 

私のログインページ:

import React, { Component, PropTypes } from 'react'; 
import { reduxForm } from 'redux-form'; 
import { loginUser } from '../../actions/index'; 
import { Link } from 'react-router'; 
import { FACEBOOKLOGIN } from '../../constants/index'; 
import googleLogin from './google_login.js'; 
import FacebookButton from './facebook_login.js'; 



function validate(values) { 
    const errors = {} 

    if (!values.email) { 
    errors.email = 'Required' 
    } else if (!/^(([^<>()\[\]\\.,;:\[email protected]"]+(\.[^<>()\[\]\\.,;:\[email protected]"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(values.email)) { 
    errors.email = 'Please enter a valid email address' 
    } 

    if (!values.password) { 
    errors.password = 'Required' 
    } 

    return errors 
} 



class LoginForm extends Component { 
    static contextTypes = { 
    router: PropTypes.object 
    }; 



    onSignIn(googleUser) { 
    var profile = googleUser.getBasicProfile(); 
    console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead 
    console.log('Name: ' + profile.getName()); 
    console.log('Image URL: ' + profile.getImageUrl()); 
    console.log('Email: ' + profile.getEmail()); 
    } 

    signOut() { 
     var auth2 = gapi.auth2.getAuthInstance(); 
     auth2.signOut().then(function() { 
     console.log('User signed out.'); 
     }); 
    } 

    onSubmit(props){ 
    this.props.loginUser(props) 
    .then(() => { 
     this.context.router.push('/'); 
    }); 
    } 

    render() { 
    const { fields: { email, password }, handleSubmit, submitting } = this.props 
    return (
     <div> 
     <form onSubmit={handleSubmit(this.props.loginUser)}> 
      <div className={`form-group ${email.touched && email.invalid ? 'has-danger' : ''}`}> 
      <label>E-mail</label> 
      <div> 
      {/* {email.touched && email.error && <div className={s.textError}>{email.error}</div>} */} 
       <input type="email" className="form-control" {...email}/> 
       <div className="email-help-login"> 
       {email.touched ? email.error : ''} 
       </div> 
      </div> 

      </div> 
      <div className={`form-group ${password.touched && password.invalid ? 'has-danger' : ''}`}> 
      <label>Password</label> 
      <div> 
      {/* {password.touched && password.error && <div className={s.textError}>{password.error}</div>} */} 
       <input type="password" className="form-control" {...password}/> 
       <div className="password-help-login"> 
       {password.touched ? password.error : ''} 
       </div> 
      </div> 
      </div> 
      <div> 
      <button type="submit" className="btn btn-primary"> 
       Login 
      </button> 
      </div> 
      <div> 
      <Link to="/" className="btn btn-danger">Cancel</Link> 
      </div> 


     </form> 
     <FacebookButton fb={FB} /> 



     <googleLogin/> 
     <a href="#" onclick="this.signOut();">Sign out</a> 


     </div> 

    ) 
    } 
} 


export default reduxForm({ 
    form: 'LoginForm', 
    fields: ['email','password'], 
    validate 
},null,{loginUser})(LoginForm) 

誰でも私にこの問題の解決を手伝ってもらえますか?

答えて

1

私はFACEBOOKLOGIN../constants/indexのデフォルトエクスポートではないと仮定しています。これを試してみてください:

import { FACEBOOKLOGIN } from "../constants/index"; 
const API_URL = "http://localhost:3000"; 
//FACEBOOKLOGIN 
export function facebookLogin(props){ 
    const request = axios.post(`${API_URL}/users`,{ 
    user: { 
     email:props.email, 
     password:props.password, 
     password_confirmation:props.password 
    } 
    }); 
    return{ 
    type: FACEBOOKLOGIN, 
    payload: request 
    } 
} 

UPDATEを:あなたの新しいエラーメッセージが表示されて、新たな問題がthisが結合に関係しています。 Reactは自動的にthisをすべてのコンポーネントメソッドに束縛して戻りますが、今はそれを自分で行う必要があります。この問題を修正するには、これにあなたのFacebookButtonコンストラクタを変更します。

constructor(props) { 
    super(props); 
    this.FB = props.fb; 
    this.state = { 
    message: "" 
    }; 

    this.onClick = this.onClick.bind(this); 
} 

私はまた、あなたがthis.onClickを呼んでいるFacebookButtonためのrenderメソッドで参照してください。それはあなたがしたいことではありません。これを試してみてください:

render() { 
    const { fields: { email, password }, handleClick, submitting } = this.props 
     return (
     <div> 
     <div className= 
     "fb-login-button" 
     data-max-rows="1" 
     data-size="medium" 
     data-show-faces="true" 
     data-auto-logout-link="true" 
     onclick={this.onClick}></div> 
      <div>{this.state.message}</div> 
     </div> 
    ); 
    } 

更新2:FBが未定義であることを伝えています。 FBがグローバルに利用可能な場合(htmlのスクリプトタグを使ってsdkを入手している場合)、それを小道具として使うのではなく、単にその方法で使用するのはなぜですか?つまり

componentDidMount() { 
    FB.Event.subscribe('auth.logout', 
     this.onLogout.bind(this)); 
    FB.Event.subscribe('auth.statusChange', 
     this.onStatusChange.bind(this)); 
} 
+0

私はすでにアクション/インデックスにこの定数を追加しました。 –

+0

右ですが、 '../ constants/index''から' FACEBOOKLOGINをインポートしました。 'FACEBOOKLOGIN'の周りに中括弧を入れてみてください。 – taylorc93

+0

はい、あなたは正しいです。中括弧を追加しました。私はエラーメッセージを更新しました。問題を理解するのに役立つでしょうか? –

関連する問題