2017-02-21 5 views
0

私のreactのアプリケーションでは、URLにパラメータidを検証し、それに応じてビューをレンダリングする必要があります。ここではサンプルコードです:コンポーネントReactJsでレンダリングする前にurlパラメータを検証するようにマウントする

routes.js

// just relevant lines of code: 
import React from 'react'; 
import { Route, IndexRoute } from 'react-router'; 
import Foo from '../containers/foo'; 

const AppRoutes = (
    <Route component={Base} path="/"> 
    <Route component={Foo} path="/url/:id"/> 
    </Route> 
); 
export default AppRoutes;  

Fooクラス

import React, { Component } from 'react'; 
import { isValid } from '../service';  

class Foo extends Component { 
    state = { 
    check : true 
    } 
    componentWillMount(){ 
    if (isValid(this.props.params.id) == false || 'undefined') { 
     console.log(isValid(this.props.params.id)); 
     this.setState({ 
     check : false 
     }); 
    } 
    } 
    render() { 
    if (!this.state.check){ 
     return(...); 
    }else{ 
     return(...); 
    } 
    }; 
} 
export default Foo; 

service.js

"use strict"; 
function createCORSRequest(method, url) { 
    var xhr = new XMLHttpRequest(); 
    if ("withCredentials" in xhr) { 
    // XHR for Chrome/Firefox/Opera/Safari. 
    xhr.open(method, url, true); 
    } else if (typeof XDomainRequest != "undefined") { 
    // XDomainRequest for IE. 
    xhr = new XDomainRequest(); 
    xhr.open(method, url); 
    } else { 
    // CORS not supported. 
    xhr = null; 
    } 
    return xhr; 
} 

function fetchId(method, url, id, callback){ 
    var xhr = createCORSRequest(method, url); 
    if (!xhr) return; 
    xhr.addEventListener("readystatechange", callback); 
    xhr.setRequestHeader("content-type", "application/json"); 
    xhr.send(JSON.stringify(query)); 
} 

function isValid(id){ 
    let url = 'https://some/api/url/'; 
    return fetchId('POST', url, id, function(){ 
    return (this.readyState===4 && this.responseText.length>0) ? true : false; 
    }); 
} 
export default {isValid} 

今が有効であるかどうかにかかわらず、undefinedは常にcomponentWillMount()のに印刷されます。 2つの問題があるようですが、私はブール値レスポンスを正しく返していないか、あるいはcomponentWillMount()を誤って利用しています。私はdocsと思って、componentWillMount()が実際にrender()の前にトリガーすることを知りました。

誰かが本当の問題を指摘し、私が間違っているところを修正してくれますか?

+1

Fooとは何を呼びますか? paramsは反応ルータから来ていますか?もしあなたのルートがどのように設定されているかを私たちに見せることができますか? –

+0

@JoPeyper 'routes.js'の関連する行について言及して質問を更新しました。まだ何かが欠落している場合はお気軽にお問い合わせください。 – adi

答えて

-1

Fooコンポーネントを呼び出すのは不明です。 しかし、あなたはクラスFooにコンストラクタがないようです。

class Foo extends Component { 
    constructor(props) { 
    super(props); 
    this.state = { check : true }; 
    } 
    componentWillMount() { 
    console.log(this.props.params.id); 
    } 
    render() { 
     //... 
    } 
} 

詳細はReact State Docsを参照してください。

+0

は役に立ちません。また、状態がコンストラクタで 'this.state'になるのは、' undefined'エラーが発生するからです – adi

+1

'this.state'と言って固定しました – styfle

0

条件付きレンダリングを実行しようとしているようです。私は自分自身に反応することを学んでいる間にこの問題を見つけました(これがあなたが探しているものと仮定します)。もしそうなら、これはあなたがそれを行うだろうかです:



ので、上記のコードブロックでは、あなたがthis.props.paramsかどうかを確認するために条件チェックのいくつかの並べ替えを行うことができます.id === 'some string'とし、それが真であればdivの最初のセットを描画します。

メッセージが表示されない場合や、別の解決策を探している場合は、メッセージしてください。

+0

また、あなたのルートではどんなIDを探していますか?電子メールの検証をしようとしていますか? – Mason0958

+0

私はあなたのためにレンダリング部分を更新しました。もう一度見てください、これは私がコンディショニングを適用する方法ですが、私はコンディショニングの問題をここでは考えていません。問題は、 'componentWillMount()'の 'console.log'は常に' undefined'を出力しますが、 'true'か' false'のどちらかでなければなりません。 妥当性検査に関して、ちょうどランダムな(製品の種類の)ID検証 – adi

+0

も、あなたが言及した3値化の解決策は、返す/レンダリングする1行だけです。そこに[反応の条件付きレンダリング]のための他の多くのスレッドがあります(http://stackoverflow.com/questions/22538638/how-to-have-conditional-elements-and-keep-dry-with-facebook-reacts-jsx ) – adi

1

注:XMLHttpRequestの残りの部分は、私がフェッチやアキシオのように私のために管理するためにライブラリを使って直接使ったことがないと分かりません。

問題は有効な方法です。

function isValid(id){ 
    let url = 'https://some/api/url/'; 
    return fetchId('POST', url, id, function(){ 
    return (this.readyState===4 && this.responseText.length>0) ? true : false; 
    }); 
} 

問題は、boolean型の戻り値が関数の内部で、isValid機能は、実際に(したがって、あなたがundefinedをログに記録され、何も返さない)fetchId関数の結果を返しています。

どうしてですか?

あなたのリクエストはバックグラウンドで実行され、実行をブロックしません。したがって、isValid関数の最後には、返すブール値はありません。

あなたはそれについて何ができますか?

isValid関数は、fetchId関数と同様に、要求が完了するまで状態の設定を延期するためにコールバックを取る必要があります。

function isValid(id, callback){ 
    let url = 'https://some/api/url/'; 
    fetchId('POST', url, id, function(){ 
    callback(this.readyState===4 && this.responseText.length>0) 
    }); 
} 

、あなたはそう

componentWillMount(){ 
    isValid(this.props.params.id, valid => { 
    if (!valid) { 
     console.log(isValid(this.props.params.id)); 
     this.setState({ 
     check : false 
     }); 
    } 
    }); 
} 

のようにそれを呼び出すしかし、私はコールバック内部のコールバックを持っており、その全て従うことがあまりにもハードになっ!

あなたは間違っていません。これらの種類の相互作用は、反応コンポーネント内で完全に実行しようとすると非常に乱雑になります。 reduxreact-reduxを使用すると、州の管理、行動、意見の懸念を簡単に区別できます。

+0

最後にこれらのコールバックは完璧なオプションではないようですが、適切な答えです。私はあなたの変更を有効なIDで適用し、それに応じて正しい部分をレンダリングしますが、秒以内に 'undefined'を表示してもう一方の部分を再描画します – adi

+0

条件' if(!valid)... 'の前に、 'console.log(valid)'と 'false'を2回、' true'を1回出力します。つまり、この機能は3回実行されています。 – adi

+1

おそらく何かが原因で、コンポーネントが少し異なる時間にマウントされている可能性があります。実行せずにデバッグするのは難しいです。この権利を得るために、あなたは本当にreduxを見たいと思うでしょう。 Reduxは、コンポーネント内の状態に関する考え方を変更し、複雑なロード状態を簡単にします。 –

関連する問題