javascript - 单击时渲染 react 组件

标签 javascript reactjs

当我们点击“添加”链接时,我正在尝试渲染 Need 组件。 以下是我的主要组件代码:

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'));

为了以防万一,下面是我的 Need 组件:

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>            
        )
    }
}

我在第一次点击添加链接时实现了我想要实现的目标,即首先在没有任何条件的情况下呈现了需求组件。当我点击“添加”时,需求组件再次呈现但是当我第二次点击“添加”链接,我没有看到任何变化。为什么会这样,我想在每次单击“添加”链接时渲染 Need 组件。

最佳答案

下面是您的问题的解决方案。我尝试尽可能接近您的代码。

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

@sean 的解释很到位。

By default, calling setState will rerender component, no matter what valid arguments you pass to setState. So yes, it should be rerendering. It doesn't appear to be rerendering because, well, it's always displaying the same thing after the first click because renderNeed is always true after every click

React 维护一个虚拟 DOM,所有 DOM 操作都在这个虚拟 DOM 中完成(在更新实际 DOM 之前)。添加 Need 组件是一种 DOM 操作。因此,第一次当我们点击“添加”时,它实际上更新了虚拟 DOM 以添加一个新的Need。现在 React diff 算法起作用了,它更新了实际的 DOM。因此,需要 组件显示在 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 再次为真,因此,React 将尝试在虚拟 DOM 中添加 Need 组件(由于以下代码)。

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

但在添加 Need 之前,React diff 算法将运行,它会看到虚拟(和实际)DOM 中已经存在一个 Need 组件,它与它试图添加的组件完全相似. 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 的所有优化。

我鼓励您浏览以下两个很棒的站点,其中正确解释了 react 差异算法。

  1. 在 Google 中搜索“Reconciliation - React”并从搜索结果中打开 facebook React 页面
  2. > https://calendar.perfplanet.com/2013/diff/

关于javascript - 单击时渲染 react 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42158143/

相关文章:

javascript - 如何调试悬而未决的 promise ,而不是使用 node-postgres 解决 Postgres 查询?

javascript - 拖动时更改 uibModal 透明度

javascript - 使用循环从 javascript 中的对象获取函数结果

javascript - 使用 reddit json 时映射未定义

reactjs - 在 React 中是否有比 onChange 更简洁的方法将输入字段连接到状态属性?

javascript - Mongoose 未保存所有字段

javascript - Jquery 自定义验证无法正常工作

reactjs - 如何将React-app-rewired与Customize-CRA集成

html - 如何将 HTML 转换为 JSX (React.js)

reactjs - 如何在 React 中声明一个二维数组?