2017-02-10 162 views
1

我試圖呈現需要組件,當我們點擊「添加」鏈接。 下面是我的主要成分代碼:渲染點擊反應組件

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Hand } from './hand.js'; 
import { Need } from './need.js'; 

class App extends React.Component{ 
    constructor() { 
    super(); 
    this.processHand = this.processHand.bind(this); 
    this.addNeed = this.addNeed.bind(this); 
    this.state = { 
     inhandMoney : " ", 
     renderNeed: false, 
    } 

    } 

    processHand(e){ 
    e.preventDefault(); 
    const handMoneyReceived = this.handMoney.value; 
    this.setState({ 
     inhandMoney: handMoneyReceived 
    });  
    } 

    addNeed(e){ 
    e.preventDefault(); 
    this.setState({ 
     renderNeed:true 
    }); 
    } 

    render(){ 

    const passNeed = ( 
      <Need/> 
    ); 

    return(
     <div> 
      <div className ="hand"> 
      <form onSubmit = {this.processHand}> 
       <input type="text" ref= {ref => this.handMoney = ref}/> 
       <input type="submit"/> 
      </form> 
      <Hand handMoney = {this.state.inhandMoney}/> 
      <Need/> 
      </div> 
      {this.state.renderNeed ? passNeed : null} 
      <a href="#" className="add" onClick = {this.addNeed}>add</a> 
     </div> 
    ) 
    } 
} 

ReactDOM.render(<App />, document.getElementById('container')); 

以下是我的極品部件,以防萬一:

import React from 'react'; 

export class Need extends React.Component{ 
constructor() { 
    super(); 
    this.processNeed = this.processNeed.bind(this); 
    this.state ={ 
     why: " ", 
     howMuch: 0 
    } 

} 

processNeed(e){ 
    e.preventDefault(); 
    const why=this.why.value; 
    const howMuch=this.howMuch.value; 
    this.setState({ 
     why:why, 
     howMuch:howMuch 
    }); 
} 

    render(){ 
     return(
      <div className ="need"> 
      <form onSubmit = {this.processNeed}> 
       <input type="text" ref= {ref => this.why = ref}/> 
       <input type="text" ref= {ref => this.howMuch = ref}/> 
       <input type="submit"/> 
      </form> 
      <div> 
       <h1>{this.state.why}</h1> 
       <h1>{this.state.howMuch}</h1> 
      </div> 
      </div>    
     ) 
    } 
} 

我正在實現我所試圖實現對第一次點擊到add鏈接,即首先需要組件被渲染,沒有任何條件。當我點擊「添加」需要組件再次呈現,但是當我第二次單擊「添加」鏈接時,我沒有看到任何更改。爲什麼是這樣,我想每次點擊「添加」鏈接時呈現需要組件。

+0

類方法需要被「綁定」。 @john_omalley的答案如下。請參閱http://stackoverflow.com/a/30721098/368697瞭解您打算用作回調的綁定類方法。 –

+0

你有沒有得到解決方案或仍然面臨問題? –

回答

1

從您的解釋中,我發現每次點擊add鏈接時都要添加Need組件。

由於您對render()方法的錯誤理解,您提供的代碼無法按照您希望的方式工作。每次點擊add鏈接時,您的<Need />組件都會重新渲染,但每次只有一個重新渲染的組件。如果您想每次單擊add鏈接時渲染新組件。您將需要使用一個包含所有<Need />組件的數組。

爲了達到同樣的效果,我創建了一個名爲needArray的狀態變量。每當你點擊add鏈接,一個新的<Need />組件將被添加到這個狀態變量中,並且將會呈現相同的組件。

constructor(props) { 
    super(props) 
    this.state = {renderNeed: false, needArray: []} 
    this.addNeed = this.addNeed.bind(this) 
} 

addNeed(e) { 
    e.preventDefault(); 
    // any another better approach can be used to generate unique key. I've used Math.random() for demo only. 
    this.setState({ 
     renderNeed: true, 
     needArray: [<Need key={Math.random()}/>, ...this.state.needArray] 
    }) 
} 

render() { 
    return (
     <div> 
     <a href="#" onClick = {this.addNeed}>add</a> 
     {this.state.renderNeed ? this.state.needArray : null} 
     </div> 
    ) 
} 

這裏是工作小提琴的鏈接。爲了簡潔起見,我只添加了所需的代碼。 JSFiddle

0
{this.state.renderNeed ? passNeed : null} 

代之以

{this.state.renderNeed && <Need/> } 
+0

不起作用!同樣的問題。 – ashish

1

嘗試:爲實現這一 <a href="#" className="add" onClick = {this.addNeed.bind(this)}>add</a>

+0

仍然無法使用! – ashish

+0

對 - 錯過了。您需要在狀態中對一組項目進行建模 - 而不是以[]開頭的布爾標誌爲false,然後每次點擊後連接一個新項目。然後您需要爲數組中的每個項目渲染一個項目。請參閱關於渲染項目數組的反應文檔(尤其是'key'屬性。 –

0

1)一種方法是:

addNeed(e){ 
    e.preventDefault(); 
    this.setState({ 
     needKey: Math.random() 
    }); 
} 

而在你的渲染,你可以添加此鍵:

<Need key={this.state.needKey} /> 

2)另一種方法是:

addNeed(e){ 
    e.preventDefault(); 
    this.setState(this.state); 
} 

3)另外,也可以用forceUpdate完成。但是,通常不建議:

addNeed(e) { 
    e.preventDefault(); 
    this.forceUpdate() 
} 
+0

不工作!!!! – ashish

0

我將創建一個初始狀態鍵與空數組,你點擊「添加」,你會增加數組的大小每一次,然後你會陣圖在render()。事情是這樣的:

constructor() { 
super(); 
    this.processHand = this.processHand.bind(this); 
    this.addNeed = this.addNeed.bind(this); 
    this.state = { 
    inhandMoney : " ", 
    fields: [], 
    } 
} 

addNeed(e){ 
    e.preventDefault(); 
    this.setState({ 
    fileds: this.state.fields.push(1), 
    }); 
} 

render() { 
    <div> 
    <div className="hand"> 
     <form onSubmit={this.processHand}> 
     <input type="text" ref={ref => this.handMoney = ref}/> 
     <input type="submit"/> 
     </form> 
     <Need/> 
    </div> 
    {this.state.fields.map(i => <Need key={i} />)} 
    <a href="#" className="add" onClick={this.addNeed}>add</a> 
    </div> 
} 
1

如果你想保持渲染收集需求,你可能要存儲在您的狀態的陣列,可以跟蹤您的需求。

否則,在此基礎上報價 -

首先需要組件被無當我點擊任何condition.and呈現「添加」極品部件再次呈現,但是當我點擊「add」鏈接第二次,我沒有看到任何變化。

看來你要根據你的修訂渲染renderNeed布爾

默認情況下,調用的setState將重新呈現組件,不管你通過對setState什麼有效的參數。所以是的,它應該是重新渲染。它似乎並沒有被重新描繪,因爲,它總是顯示首次點擊後,同樣的事情,因爲renderNeed始終是真實的每一次點擊

後,這是一個很好的資源:ReactJS - Does render get called any time "setState" is called?

作爲做作例如,如果你真的想「重新呈現」你的組件,你可以做一些瑣碎的像renderNeed

addNeed(e){ 
    e.preventDefault(); 
    this.setState((prevState, props) => ({ 
     renderNeed: !prevState.renderNeed 
    }); 
    } 

創建撥動它不建議這樣做,因爲你的addNeed功能沒有做什麼顧名思義.. 。

也有點小提琴證明它是重新呈現

https://jsfiddle.net/jwm6k66c/2131/

希望這有助於。

2

以下是解決方案小提箱爲您的問題。我試圖儘可能接近你的代碼。

https://jsfiddle.net/birjubaba/t0yusos9/3/

通過@sean給出的解釋是即期。

默認情況下,無論您傳遞給setState的有效參數是什麼,默認情況下調用setState都會重新渲染組件。所以是的,應該是 重新渲染。它似乎並沒有被重新描繪,因爲,這是 總是第一個點擊後顯示同樣的事情,因爲 renderNeed始終是真實的後,每點擊

陣營保持虛擬DOM和所有的DOM操作完成在這個虛擬的DOM中(在更新實際的DOM之前)。添加Need組件是一種DOM操作。所以,第一次當我們點擊「添加」時,它實際上更新了虛擬DOM以添加新的Need。現在反應差異算法的作品,它會更新實際的DOM。因此,Need組件顯示在UI中。該DOM看起來會象下面這樣:當「添加」點擊

div 
|- div (class=hand) 
     |-form 
     |-input (type=text) 
     |-input (type=submit) 
     |- Hand 
     |- Need 
|-Need (added by clicking on add anchor tag) 
|-a (class=add) 

下一次,this.state.renderNeed是真實的了,所以,陣營將嘗試在虛擬DOM需要添加組件(由於下面的代碼) 。

{this.state.renderNeed ? passNeed : null} 
<a href="#" className="add" onClick = {this.addNeed}>add</a> 

但添加Need之前,作出反應差異算法運行,它會看到已經有一個存在於虛擬(和實際)DOM極品分量正好是一個類似於它試圖添加。 React會認爲這兩個DOM是相同的,並且UI中沒有更新。

你加的要求是像下面的東西:

div 
|- div (class=hand) 
     |-form 
     |-input (type=text) 
     |-input (type=submit) 
     |- Hand 
     |- Need 
|-Need (added by clicking on add anchor tag) 
|-Need (added by clicking on add anchor tag) 
|-Need (added by clicking on add anchor tag) 
|-Need (added by clicking on add anchor tag) 
|-a (class=add) 

這可以通過保持Need組件的陣列和渲染他們點擊添加來實現。 React diff算法將負責更新虛擬DOM和實際DOM的所有優化。

我鼓勵你通過下面兩個精彩的網站,其中反應差異算法正確解釋。

  1. 搜索「和解 - 響應」在谷歌和打開的Facebook頁面反應從搜索結果
  2. https://calendar.perfplanet.com/2013/diff/
+1

ha!感謝您承認我的答案:) –

+0

'&&'運算符的基本規則,如果第一個條件爲真,條件被評估。所以在這裏如果'this.state.renderNeed'爲true,那麼會計算出第二個調用方法(this.renderNeedArray()'),它只是確保'this.state.renderNeed'爲true時,只有'renderNeedArray )'被調用。 –

+0

謝謝,我還想在完成添加需求後添加所有需要組件中的「多少」的所有值。 – ashish