2017-04-17 4 views
0

動的に生成されたdivのコンポーネントHomeScreen.jsをレンダリングしようとしています。私はこれを少しでもうまく動かすことができますが、動的に生成されたdivからコンポーネントを分離することはできません。さらに、HomeScreen.jsをクリックしたdivだけにレンダリングしようとしていますが、現在、すべての部門のHomeScreen.jsを開きます。反応内の各動的divのコンポーネントを表示

(これは、接触アプリで、動的に生成されるのdivはコンタクトである。私はちょうどクリックます各連絡先の連絡先情報を表示しようとしている)

私は現在の機能のとのスクリーンショットを添付しました機能は、私はいくつかの洞察を使用することができ

Current Functionality

を取得しようとしています。

import store from '../libs/store.js'; 
var jsforce = require('jsforce'); 

class menuScreen extends React.Component { 

    constructor(props) { 
     super(props) 

     const data = store.getState(); 

     this.state = { 

      username: '', 
      messages: data.messages, 
      records: [], 
      showModal: false, 
      showChat: false 

     } 
    } 

    handleSearch(e) { 
     this.setState({ 
      username: e.target.value 
     }) 
    } 

    handleChange(evt) { 
     this.setState({ 
      username: evt.target.value.substr(0, 100) 
     }); 

    } 

    onClick(e) { 
     e.preventDefault(); 
     this.setState({ 
      showChat: !this.state.showChat 
     }) 
    } 

    onLinkClicked() { 


     var conn = new jsforce.Connection({ 
      serverUrl: 'https://cs63.salesforce.com', 
      accessToken: sessionStorage.getItem('token') 
     }) 

     var parent = this.state.username 
     //console.log(this.state.username) 
     conn.sobject("Contact").find({ 
       LastName: { 
        $like: parent 
       } 
      }, 'Id, Name, Phone, Account.Name' 

     ).sort('-CreatedDate Name'). 
     limit(5).skip(10).execute(function(err, records) { 
      if (err) { 
       return console.error(err); 
      } 
      for (var i = 0; i < records.length; i++) { 
       var record = (records[i]); 
       console.log("Name: " + record.Name); 
       console.log("Phone: " + record.Phone); 
       console.log("Account Name: " + record.Account.Name); 

      } 
      this.setState({ 
       records: records 
      }) 

      this.setState({ 
       showChat: !this.state.showChat 
      }) 

     }.bind(this)) 

    } 

    render() { 
     return (
      <div className='menubox' id='menubox'> 

       <div className="boxbox"> 
        <input className="search" type="text" placeholder="Contact Last Name" onChange={this.handleChange.bind(this)} value={this.state.username} /> 
        <input className="submit" type="submit" onClick={this.onLinkClicked.bind(this)} value="GO" /></div> 
       <div> 
        <div> 
         {this.state.records.map(record => (
          <div className="info-block block-info clearfix"> 
           <div className="square-box pull-left"> 
            <span className="glyphicon glyphicon-user glyphicon-lg"></span> 
           </div> 
           <h5>{record.Name}</h5> 
           <h4>{record.Phone}</h4> 
           <p>{record.Account.Name}</p> 

            **//Trying to render home.js when Chat Bubble is clicked.** 

            <a onClick={this.onClick.bind(this)}> 
            <img src="./img/speechbubble.png" className="textIcon" /> 
            {this.state.showChat && < HomeScreen/>} 
           </a> 
          </div> 
         ))} 
        </div> 

       </div> 
      </div> 

     ) 
    } 

} 

export default menuScreen; 

答えて

1

理由は、あなたがすべてのdynamic divを制御するために、単一のstate変数を使用している、あなたはstate変数にshowChat = []を使用し、arrayを使用するように各要素の各値を必要とする、だからではなく、showChat = falseのさ。 arrayの値をonClick関数に変更するには、onClickの要素のインデックスを渡して、そのインデックスを使用して特定の値を変更する必要があります。

その他の変更点については、コードとコメントを確認してください。動作するはずです。

使用この:

import store from '../libs/store.js'; 
var jsforce = require('jsforce'); 

class menuScreen extends React.Component { 

    constructor(props) { 
     super(props) 

     const data = store.getState(); 

     this.state = { 
      username: '', 
      messages: data.messages, 
      records: [], 
      showModal: false, 
      showChat: [] //initially blank array 
     } 
    } 

    handleSearch(e) { 
     this.setState({ 
      username: e.target.value 
     }) 
    } 

    handleChange(evt) { 
     this.setState({ 
      username: evt.target.value.substr(0, 100) 
     }); 

    } 

    onClick(i, e) { // pass the index on item clicked 
     e.preventDefault(); 

     let showChat = this.state.showChat.slice(); 
     showChat[i] = !showChat[i]; //use that index to change the specific value 
     this.setState({ showChat }) 
    } 

    onLinkClicked() { 

     var conn = new jsforce.Connection({ 
      serverUrl: 'https://cs63.salesforce.com', 
      accessToken: sessionStorage.getItem('token') 
     }) 

     var parent = this.state.username 
     //console.log(this.state.username) 
     conn.sobject("Contact").find({ 
       LastName: { 
        $like: parent 
       } 
      }, 'Id, Name, Phone, Account.Name' 

     ).sort('-CreatedDate Name'). 
     limit(5).skip(10).execute((err, records) => { //use arrow function 
      if (err) { 
       return console.error(err); 
      } 
      // this loop is not required 
      /* 
      for (var i = 0; i < records.length; i++) { 
       var record = (records[i]); 
       console.log("Name: " + record.Name); 
       console.log("Phone: " + record.Phone); 
       console.log("Account Name: " + record.Account.Name); 

      } 
      */ 
      console.log('recoreds values', records); 
      this.setState({ 
       records: records, 
      }) 
     }) 

    } 

    render() { 
     return (
      <div className='menubox' id='menubox'> 

       <div className="boxbox"> 
        <input className="search" type="text" placeholder="Contact Last Name" onChange={this.handleChange.bind(this)} value={this.state.username} /> 
        <input className="submit" type="submit" onClick={this.onLinkClicked.bind(this)} value="GO" /></div> 
       <div> 
        <div> 
         /*use the index also in map*/ 
         {this.state.records.map((record, i) => (
          <div className="info-block block-info clearfix"> 
           <div className="square-box pull-left"> 
            <span className="glyphicon glyphicon-user glyphicon-lg"></span> 
           </div> 
           <h5>{record.Name}</h5> 
           <h4>{record.Phone}</h4> 
           <p>{record.Account.Name}</p> 

            <a onClick={this.onClick.bind(this, i)}> 
            <img src="./img/speechbubble.png" className="textIcon" /> 
            {this.state.showChat[i] && < HomeScreen/>} 
         {/*use this.state.showChat[i] specific value*/} 
           </a> 
          </div> 
         ))} 
        </div> 

       </div> 
      </div> 

     ) 
    } 

} 

export default menuScreen; 

提案:代わりにこのように、コンストラクタで結合を定義し、レンダリング中の結合方法の:

this.handleChange = this.handleChange.bind(this); 

直接利用した:

onChange={this.handleChange} 
+0

ありがとうございます。これは非常に役に立ちました! 1つの質問、どうすれば親のmenuboxコンテナの外に を開くことができますか? –

+0

あなたはmenubarの親コンポーネントからあなたを得ていませんか? –

+0

はい、私はメニューバーの外にホームスクリーンを表示しようとしています –

0

私はMayanのarr使用に関する答えに同意しますshowChatの場合、そのアイデアを踏まえて、各連絡先を別々のコンポーネントにすることができなかった理由はありますか?個人的には、Contactコンポーネントなどの子コンポーネントの配列をレンダリングし、外側のmenuScreenコンポーネントの状態からそれぞれのコンポーネントに小道具を渡します。

class Contact extends React.Component { 
    constructor(props) { 
    super(props) 
    this.state = {} 
    } 

    render() { 
    return (
     <div className="info-block block-info clearfix"> 
     <div className="square-box pull-left"> 
      <span className="glyphicon glyphicon-user glyphicon-lg"></span> 
     </div> 
     <h5>{record.Name}</h5> 
     <h4>{record.Phone}</h4> 
     <p>{record.Account.Name}</p> 

     <a onClick={this.props.onClick}> 
      <img src="./img/speechbubble.png" className="textIcon" /> 
      {this.props.showChat && < HomeScreen/>} 
     </a> 
     </div> 
    ) 
    } 
} 

そして、あなたがそうのようなあなたのmenuScreenコンポーネントでそれを使用することができます。

import store from '../libs/store.js'; 
var jsforce = require('jsforce'); 


class menuScreen extends React.Component { 

    constructor(props) { 
     super(props) 

     const data = store.getState(); 

     this.state = { 
      username: '', 
      messages: data.messages, 
      records: [], 
      showModal: false, 
      showChat: [] 
     } 
    } 

    handleSearch(e) { 
     this.setState({ 
      username: e.target.value 
     }) 
    } 

    handleChange(evt) { 
     this.setState({ 
      username: evt.target.value.substr(0, 100) 
     }); 

    } 

    onClick(i, e) { 
     e.preventDefault(); 

     let showChat = this.state.showChat.slice(); 
     showChat[i] = !showChat[i]; 
     this.setState({ showChat }) 
    } 

    onLinkClicked() { 

     var conn = new jsforce.Connection({ 
      serverUrl: 'https://cs63.salesforce.com', 
      accessToken: sessionStorage.getItem('token') 
     }) 

     var parent = this.state.username 
     //console.log(this.state.username) 
     conn.sobject("Contact").find({ 
       LastName: { 
        $like: parent 
       } 
      }, 'Id, Name, Phone, Account.Name' 

     ).sort('-CreatedDate Name'). 
     limit(5).skip(10).execute((err, records) => { 
      if (err) { 
       return console.error(err); 
      } 
      // this loop is not required 
      /* 
      for (var i = 0; i < records.length; i++) { 
       var record = (records[i]); 
       console.log("Name: " + record.Name); 
       console.log("Phone: " + record.Phone); 
       console.log("Account Name: " + record.Account.Name); 

      } 
      */ 
      console.log('recoreds values', records); 
      this.setState({ 
       records: records, 
      }) 
     }) 

    } 

    render() { 
     return (
      <div className='menubox' id='menubox'> 

       <div className="boxbox"> 
        <input className="search" type="text" placeholder="Contact Last Name" onChange={this.handleChange.bind(this)} value={this.state.username} /> 
        <input className="submit" type="submit" onClick={this.onLinkClicked.bind(this)} value="GO" /></div> 
       <div> 
        <div> 
         {this.state.records.map((record, i) => (
          <Contact onClick={onClick.bind(this, i)} showChat={this.state.showChat[i]} /> 
         ))} 
        </div> 

       </div> 
      </div> 

     ) 
    } 

} 

export default menuScreen; 

だけ答えより意見の多くのかもしれないが、それはコンポーネントの状態からプレゼンテーションを分離する方が良いでしょう。子コンポーネントのonClick関数を実行する前に子のContactコンポーネントがまだ他のアクションを実行できるため、それはデコレータに似ています。

関連する問題