2017-01-13 25 views
1

私はJSXとES6を使ってリアクションを学んでいます。コンポーネントを作成し、ReactRouter4を使用してさまざまなビューにルーティングする方法についてかなり適切な扱いをしています。1つのReactコンポーネントにデータを入力して別のReactコンポーネントにレンダリングする方法は?

私がまだ把握できなかったことは、たとえば、ポートフォリオの作業の詳細を入力し、すべての作業を別のページ、おそらくPortfolioページにレンダリングする管理ページを作成する方法です。

ここに私が持っているものがあります。

App.jsPortfolio.jsコンポーネント

import React from 'react'; 

import Navigation from './Navigation'; 
import Title from './Title'; 
import Portfolio from './Portfolio'; 

class App extends React.Component { 
    render() { 
    return(
     <div className="container-fluid"> 
     <div className="container"> 
      <div className="row"> 
      <div className="col-sm-12"> 
       <Navigation /> 
       <Title title="kuality.io"/> 
       <section className="app"> 
       <Portfolio works={this.props.works} /> 
       </section> 
      </div> 
      </div> 
     </div> 
     </div> 
    ) 
    } 
} 

export default App; 

Portfolio.jsコンポーネントがaddWork()という名前のユニークな方法で、方法componentWillMount()componentWillUnmount()は状態を処理するために反応し、デフォルトrender()をバインドするコンストラクタを持ってロードします。このコンポーネントについて言及するもう1つのことは、Firebase経由でオンラインDBにすべての詳細を持っている../baseというコンポーネントを呼び出していることです。ですから、それがどこにあるのかが関係していれば、そうでなければそれを汗ばませないでください。私は、私は別のコンポーネントを作ったし、質問に本当に関係ありませんしているだけのリスト項目であるWorkコンポーネントを介してマッピングしていますObjectの内部

import React from 'react'; 

import Work from './Work'; 
import Admin from './Admin'; 
import base from '../base'; 

class Portfolio extends React.Component { 
    constructor() { 
    super(); 

    this.addWork = this.addWork.bind(this); 

    // getInitialState 
    this.state = { 
     works: {} 
    }; 
    } 
    componentWillMount() { 
    this.ref = base.syncState(`/works` 
     , { 
     context: this, 
     state: 'works' 
     }) 
    } 
    componentWillUnmount() { 
    base.removeBinding(this.ref); 
    } 
    addWork(work) { 
    // update our state 
    const works = {...this.state.works}; 
    // add in our new works with a timestamp in seconds since Jan 1st 1970 
    const timestamp = Date.now(); 
    works[`work-${timestamp}`] = work; 
    // set state 
    this.setState({ works }); 
    } 
    render() { 
    return(
     <div> 
     <section className="portfolio"> 
      <h3>Portfolio</h3> 
      <ul className="list-of-work"> 
      { 
       Object 
       .keys(this.state.works) 
       .map(key => <Work key={key} details={this.state.works[key]}/>) 
      } 
      </ul> 
     </section> 
     </div> 
    ) 
    } 
} 

export default Portfolio; 

最後に、私はAdmin.jsAddWorkForm.jsのコンポーネントを持っています。私はAddWorkForm.jsを抽象化しました。なぜなら、基本的にはReactコンポーネントの背後にある主な考え方なので、別の場所で使うことができたからです。

import React from 'react'; 
import { render } from 'react-dom'; 
// To render one method from a package user curly brackets, you would have to know what method you wan though 
import { BrowserRouter, Match, Miss} from 'react-router'; 

import './css/normalize.css'; 
import './css/bootstrap.css'; 
import './css/style.css'; 

// import '../js/bootstrap.js'; 

import App from './components/App'; 
import WorkItem from './components/WorkItem'; 
import Capability from './components/Capability'; 
import Connect from './components/Connect'; 
import NotFound from './components/NotFound'; 
import Admin from './components/Admin'; 

const Root =()=> { 
    return(
    <BrowserRouter> 
     <div> 
     <Match exactly pattern="/" component={App} /> 
     <Match pattern="/work/:workId" component={WorkItem} /> 
     <Match exactly pattern="/capability" component={Capability} /> 
     <Match exactly pattern="/connect" component={Connect} /> 
     <Match exactly pattern="/admin" component={Admin} /> 
     <Miss component={NotFound} /> 
     </div> 
    </BrowserRouter> 
) 
} 

render (<Root />, document.querySelector('#main')); 

import React from 'react'; 

import Title from './Title'; 
import AddWorkForm from './AddWorkForm'; 

class Admin extends React.Component { 
    constructor() { 
    super(); 

    this.addWork = this.addWork.bind(this); 

    // getInitialState 
    this.state = { 
     works: {} 
    }; 
    } 

    addWork(work) { 
    // update our state 
    const works = {...this.state.works}; 
    // add in our new works with a timestamp in seconds since Jan 1st 1970 
    const timestamp = Date.now(); 
    works[`work-${timestamp}`] = work; 
    // set state 
    this.setState({ works }); 
    } 
    render() { 
    return(
     <div className="container-fluid"> 
     <div className="container"> 
      <div className="row"> 
      <div className="col-sm-12"> 
       <Title title="Admin"/> 
       <section className="admin"> 
       <AddWorkForm addWork={this.addWork} /> 
       </section> 
      </div> 
      </div> 
     </div> 
     </div> 

    ) 
    } 
} 

export default Admin; 

onSubmitが作成したオブジェクト、フォームここ

import React from 'react'; 

class AddWorkForm extends React.Component { 
    createWork(event) { 
    event.preventDefault(); 
    console.log('Creating some work'); 
    const work = { 
     name: this.name.value, 
     desc: this.desc.value, 
     image: this.image.value 
    } 
    this.props.addWork(work); 
    this.workForm.reset(); 
    } 

    render() { 
    return(
     <form ref={(input) => this.workForm = input} className="work-edit form-group" onSubmit={(e) => this.createWork(e)}> 
     <input ref={(input) => this.name = input} type="text" className="form-control" placeholder="Work Title"/> 
     <textarea ref={(input) => this.desc = input} type="text" className="form-control" placeholder="Work Description"></textarea> 
     <input ref={(input) => this.image = input} type="text" className="form-control" placeholder="Work Image"/> 
     <button type="submit" className="btn btn-primary">+Add Work</button> 
     </form> 
    ) 
    } 
} 

export default AddWorkForm; 

をリセットすることは基本的な形態であるAddWorkForm.js成分は、私はを使用している含まれているファイルであります

これは私が試したものであり、達成できなかったものです。それはおそらくthis.propsの解決策でした。オブジェクトを作成してPortfolio.jsコンポーネントにスローさせて、Work.jsコンポーネントを使用してレンダリングできるようにし、オブジェクトをDBに追加しないように、Admin.jsコンポーネントにworkを作成する必要があります。

これは、同じページにすべてのコンポーネントを配置するときに機能します。これは、ポートフォリオにアクセスする誰かが作業を追加できるため、理想的ではありません。認証を学ぶプロセスと、ユーザーの資格情報に基づいてそのコンポーネントを表示または非表示にする方法を開始することはできますが、管理ページを個別のビューにまとめておくことができるという非常に貴重なスキルを学ぶことができます私はそうすることを学ぶための別のアプリケーションを見ています。

私はここで失敗していると判断できるかもしれません。

Btw、私はNav.jsTitle.jsのような他のコンポーネントを持っていることを理解していますが、例を説明するためには必要ありません。

ありがとうございます。

+4

TLDR。同じレベルまたは異なる支店にある2つのコンポーネント間でデータを交換することはできません。それらを格納する親コンポーネントか、Reduxのようなものが必要です。 – zurfyx

+0

@ zurfyxが何を言っているかをエコーする。 AdminとPortfolioの両方の親コンポーネントに状態を格納することは、おそらく最初の良いアプローチです。あなたは本当に反応ルータをどこかで使用していますか?あなたのマッチコンポーネントがどこにコードを表示できますか? – azium

+0

@zurfyxさて、私はそれを調べます。 – MARS

答えて

0

コンポーネントを小道具として渡すことができます。リアクタールーターを使用する場合は、named componentsを使用できます。

兄弟間のデータ共有では、コンテキストを使用することもできますが、親コンポーネントにデータを持たせることをお勧めしますが、これはis not advisedであり、将来のバージョンでは使用できない可能性があります。

別のコンポーネントで何かを作成する必要がある場合(理由は分かりませんが)、レンダリングする関数を渡すことができます。

関連する問題