2017-02-10 112 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