2017-05-06 14 views
1

SubmitForm -parent->結果-parent->プレゼンテーション -parent-> ButtonBackToSearchReactJs - どのように私は私がしようとしているバックだけで最初の親

を表示するには、ネストされた子コンポーネントの表示から行くことができますReactJsで正しい考え方を学び、単一ページアプリケーションを作成する方法を学びます。

私はReactでWikipedia Viewerを構築しています。私の< SubmitForm />コンポーネントで私のユーザがデータを入力した場合、<結果/>コンポーネントデータが準備されています。 次は<プレゼンテーション/>コンポーネントに示されています。 <プレゼンテーション/>コンポーネントがアクティブな場合は、検索ウィンドウを使用して< SubmitForm />に隠します。

および<プレゼンテーション/>コンポーネントは、最後のコンポーネントの親です。< ButtonBackToSearch />このコンポーネントには、次のコードを含むボタンが1つあります。

import React from 'react'; 

export default class ButtonBackToSearch extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {isBackToggleOn: false}; 

    // This binding is necessary to make `this` work in the callback 
    this.handleClick = this.handleClick.bind(this); 
    } 

    handleClick() { 
    this.setState({isBackToggleOn: true}); 
    } 

    render() { 
    return (
     <div> 
     <button onClick={this.handleClick}> 
      BACK 
     </button> 
     </div> 
    ); 
    } 
} 

私は深刻な謎を持っています。ユーザーが「戻る」ボタンをクリックしてisBackToggleOnがtrueの場合、次の検索の準備に、結果、プレゼンテーション、ButtonBackToSearch、そして< SubmitForm /に戻って、ロードされたコンポーネントのすべてを「破棄」できますか?

もちろん、ページをリロードすることはできますが、すべてのページ(F5)をリロードすることは不正行為のようなものでしょうか?

Reactでこれを行う正しい方法は何ですか?

enter image description here enter image description here

これは私のSubmitFormコードです:ButtonBackToSearchSubmitForm自身の子供を作ることになり、これを行うために

import React from 'react'; 
import axios from 'axios'; 

import Title from './Title'; 
import Results from './Results'; 

export default class SubmitForm extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     data: null, 
     value: '', 
     display: '' 
    }; 
    this.handleChange = this.handleChange.bind(this); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    } 

    axiosStart() { 
    const wikiApiUrl = 'https://en.wikipedia.org/w/api.php?action=opensearch&format=json&origin=*&search='; 
    const wikiApiUrlWithQuery = wikiApiUrl + this.state.value; 
    axios.get(wikiApiUrlWithQuery) 
     .then(response => { 
     console.log('@axiosStart was launched by user!'); 
     this.setState(Object.assign({}, this.state, { data: response.data })) 
     }) 
     .catch(err => { 
     console.log('Error: => ' + err); 
     this.setState(Object.assign({}, this.state, { data: 'error' })) 
     }); 
    this.setState({display: 'displayNone'}); 
    } 

    handleChange(event) { 
    this.setState({value: event.target.value}); 
    } 

    handleSubmit(event) { 
    console.log(('An input was submitted: ' + this.state.value)); 
    // handle change has just updated state 
    // now app can start axios with entered query 
    // as soon as user submits 
    this.axiosStart(); 
    event.preventDefault(); 
    } 

    render() { 
    return (
     <div className="container"> 
     <div className={this.state.display}> 
     <form onSubmit={this.handleSubmit}> 
      <label> 
      <Title /> 
      <input className="wiki_query" type="text" value={this.state.value} onChange={this.handleChange} autoFocus /> 
      </label> 
      <button className="btn btn-default" type="submit" value="Submit">Search</button> 
     </form> 
     </div> 
     <Results dataReady={this.state.data} /> 
     </div> 
    ); 
    } 
} 

答えて

1

私は、ユーザーに表示するためにどのような画面管理するの3つの要素 MainScreen Form Results

MainScreenを持っているでしょう。

BackButtonは、クリックされたときにコールバックすることができます。ハンドラはMainScreenになり、表示する画面の状態が変更されます。

1

一つの方法。あなたが説明したように、それは送信フォーム自体の状態を変更し、PresentationまたはResultsコンポーネントへの実際の接続はありません。これは、私の見解では、この種の相互作用を行う最もクリーンな「反応する」方法であろう。

実生活はそれより少し複雑かもしれませんが、言及されていない他の理由のために、ボタンはネストされたコンポーネントの子でなければならないと主張するかもしれません。この場合、2つの方法があります:

  1. contextを使用してください。最も単純なケースでは、SubmitFormインスタンスをコンテキストに配置し、メソッドgoBackを公開します。次に、このメソッドをボタンから呼び出してフォームインスタンスを送信し、このメソッドを呼び出します。

  2. すべてのコンポーネントを必須のプロパティparentにします。この方法で、階層ツリーを常に上に移動し、必要な親を見つけることができます。その後、#1と同じことをします。それはちょっと残酷に聞こえるかもしれませんが、便利かもしれません。

P.S.

  1. SubmitFormで定義された "goBack"関数に渡されるハンドラをすべてのコンポーネントに渡します。これは#2の非常に醜いバリエーションです。あなたはこのようにすることをお勧めしません。結果、フォームまたはデフォルト:
関連する問題