0

Meteor アプリでmeteor-useraccountsパッケージをReactと統合しようとしています。私はかなり遠くまで来ましたがhistory.push()、コールバック関数としてまたは同等のものを実装するのに苦労していますAccountsTemplate.logout()-後者は、ユーザーをログアウトする方法が組み込まれています。

コールバック関数の構成は次のように行われます。

AccountsTemplates.configure({
    onLogoutHook: myLogoutFunc
})

しかし、React.Component の「クラス」内でこれを行うことはできません。したがって、ブラウザの履歴を使用するコールバック関数を定義する必要がありますが、Components スコープの外側にあると思います。

サインイン/アウト ボタンを押す場合、次のような解決策を見つけました。

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

        this.state = {
            loggedIn: Meteor.userId() ? true : false,
            redirect: false
        }

        this.redirectToSignIn = this.redirectToSignIn.bind(this);

        window.logInOutButton = this;
    }

    redirectToSignIn() {
        if (!this.state.loggedIn && document.location.pathname !== "/signIn")
            this.setState({redirect: <Redirect to="/signIn" />});
    }

    render() {
        const { redirect } = this.state
        return (
            <li className="nav-item">
                {redirect}
                <a className="nav-link" href="#"
                    onClick={Meteor.userId() ? AccountsTemplates.logout : this.redirectToSignIn}>
                    {Meteor.userId() ? "Sign Out" : "Sign In"}
                </a>
            </li>
        )
    }
}

ご覧のとおり、たとえば、redirectToSignIn()メソッドをグローバルウィンドウオブジェクトのメンバーにして、外部からメソッドを呼び出そうとしました。気分が悪く、どちらも機能しません:

var myLogoutFunc = () =>
    window.logInOutButton.redirectToSignIn();

次のアプローチも試しました。

var myLogoutFunc = withRouter(({history}) => 
    <div onLoad={history.push="/signIn"}>
    </div>
) 

ただし、これは機能しませんwithRouter。コンポーネントがパラメーターとして必要なためです。少なくとも、これは私が次のエラーを説明しようとする方法です:

Exception in delivering result of invoking 'logout': TypeError: "props is undefined"

withRouterモジュールでこれを読んだ後:

var withRouter = function withRouter(Component) {
  var C = function C(props) {
     ...

これをどのように解決しますか?

4

2 に答える 2

0

正直なところ、アカウント システムの UI を作成するためにパッケージを使用するというアイデアは断念しました。

パッケージmeteor-useraccountsは Blaze 用に作成されました。Meteor の公式ドキュメントで{{> atForm }}は、サインイン、サインアップなどのフォームをレンダリングするテンプレートを React.Component にラップすることを推奨していますが、特に処理で非互換性を引き起こすことがわかりました。ルート。(パッケージgadicc:blaze-react-componentをラッピングに使用していました。)最終的に、このブラックボックスを理解しようとしていることに気付きました。もう 1 つは、bootstrap4 の事前スタイリング用です。たとえば、メールの確認も機能しませんでした。

そこで、すべてをダンプすることにし、Meteor Accountsと Meteor Passwords APIの上に UI 全体とロジックを自分で構築し始めました。

リダイレクトは、自分の React.Component 内で実行できるため、非常に簡単です。あなたがする必要がある唯一のことはimport { withRouter } from 'react-router';、 そして最後にリダイレクトするためにexport default withRouter(LogInOutButton);使用することができます:this.props.history.push("/signIn")

import React, { Component } from 'react';
import { withRouter } from 'react-router';

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

        this.state = {
            loggedIn: Meteor.userId() ? true : false,
        }

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

    redirectToSignIn() {
        if (this.state.loggedIn)
            Meteor.logout()
        if (document.location.pathname !== "/signIn")
            this.props.history.push("/signIn")
    }

    render() {
        return (
            <li className="nav-item">
                <a className="nav-link" href="#"
                    onClick={this.redirectToSignIn}>
                    {Meteor.userId() ? "Sign Out" : "Sign In"}
                </a>
            </li>
        )
    }
}

export default withRouter(LogInOutButton);

PS: (あくまで私の意見です)もちろん、アカウント システム用の独自の UI/ロジックを構築する際に解決すべきことがあります。たとえば、フォームの検証。(HTML5 検証の上に構築することにしましたが、bootstrap4を使用して独自の視覚的フィードバックを追加します。)

MeteorReact の場合、現時点では機能するパッケージがまったくないだけだと思います。私はそれらすべてを試しました、信じてください。それらはすべて (React と統合しようとしたときに) お尻の痛みであるか、十分にカスタマイズできませんでした。最初から時間をかけて自分のものを作っていたら、もう終わっていたでしょう。そして、自分でそれを行うことの素晴らしい点は、それがどのように機能するかを知っていて、後で簡単に改良して再利用できることです.

Meteor プロジェクトはここ数年で急速に進歩し、変化しているため、これは依存関係を低く保つのにも役立ちます。何をしたかがわかれば、プロジェクトを最新の状態に保つのが簡単になります。

于 2018-12-30T09:30:36.357 に答える