2017-04-17 60 views
0

我想呈現一個組件HomeScreen.js動態生成的div。我能夠得到這個有點工作,但我不能夠從動態生成的div分離組件,此外我只是試圖渲染HomeScreen.js只有被點擊的div,但功能我目前已爲所有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

原因是,使用的是單state變量來控制所有的dynamic div,你需要使用一個array,每個元素的每個值,所以不是showChat = false,在state變量使用showChat = []。若要更改onClick函數中的array的值,您需要傳遞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

謝謝。這非常有幫助!有一個問題,我怎樣才能在父母的menubox容器外打開 ? –

+0

沒有得到你,從菜單欄的父組件? –

+0

是的,我試圖顯示菜單外的主屏幕 –

0

我同意Mayank關於使用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; 

可能不止一個答案的意見,但它通常單獨介紹,從狀態成分更好。這種方式也更具可擴展性,因爲在運行menuScreen組件的onClick函數之前,子組件的接觸組件仍然可以執行其他操作,使其幾乎像裝飾器一樣。