How to add HTML with onClick event in React

0

It may seem like a repeated question, but the examples I found are complicated and need a pre-defined array, I do not have that, I'd like to know the simplest way to add an element to the DOM with React, it's like jQuery and I should change the state of the component.

Update 1 : I'm adding code to explain to Marcelo my problem better.

<tr>
  <td>
    <InputMask maxlenght="10" className="form-control" mask="99/99/9999"  type="text"/>
  </td>
  <td>
    <InputMask style={{'fontSize': '13px'}} mask="9999/99-99999"   className="form-control" type="text"/>
  </td>
  <td>
    <InputMask maxlenght="10" className="form-control"  type="text"/>
  </td>
  <td >
    <InputMask className="form-control"  type="text"/>
  </td>
  <td>
    <InputMask className="form-control somatorio"  maskChar="0" mask="99:99" type="text"/>
  </td>
</tr>

Well, I'd like to add this tr to a tbody , whenever the user clicks a button , but when adding, it deletes the content already in tbody .

Update 2 : I changed the way it is done, using state, follow the code

Component

constructor(props) {
  super(props);
  this.state = {
    rows: []
  };
}

insereRow() {
  this.setState(prevState => ({
    rows: [...prevState.rows, 'row1']
  }))
}

Rendering in HTML, via map

{this.state.rows.map((rows) =>
<tr key={rows}>
  <td>
    {rows}
    <InputMask maxlenght="10" className="form-control" mask="99/99/9999"  type="text"/>
  </td>
  <td>
    <InputMask style={{'fontSize': '13px'}} mask="9999/99-99999"   className="form-control" type="text"/>
  </td>
  <td>
    <InputMask maxlenght="10" className="form-control"  type="text"/>
  </td>
  <td >
    <InputMask className="form-control"  type="text"/>
  </td>
  <td>
    <InputMask className="form-control somatorio"  maskchar="0" mask="99:99" type="text"/>
  </td>
</tr>
)}

Button that should add an item in the array, so that another tr

<button type="button" onClick={this.insereRow} className="btn btn-primary"><i className="glyphicon glyphicon-plus"></i> Atividades
                </button>

However this error in the this.setState = this is undefined line

    
asked by anonymous 01.03.2018 / 21:23

3 answers

1

Here in my case I created a component App and a called Hello , what I did here is:

-When the user clicks <h1>Welcome...</h1> , the ReactDOM.render component will be rendered with Hello

class Hello extends React.Component {
  render()
  {
    return(
      <h1>Hello, I was inserted beibi :D</h1>
    );
  }
}
class App extends React.Component {
  insertHtml() {
    let target = document.querySelector(".target");

    ReactDOM.render(<Hello/>, target);
  }
  render() {
    return(
      <div>
        <h1 onClick={this.insertHtml.bind(this)}>
          Welcome, click over me
        </h1>

        <div className={"target"}></div>
      </div>
    );
  }
}

ReactDOM.render(<App/>, document.querySelector(".root"));
<div class="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

You could use:

target.innerHTML = renderToString(<Hello/>);

But since you'll want to use "<Hello/>" to be dynamic, then it's not recommended to use renderToString here. renderToString is more to Sever Side Rendering

    
02.03.2018 / 12:34
0

You must use state , it should contain component-specific data that may change over time. use.

  

State should be a simple JavaScript object.

For a better understanding, let's create a component for working with contacts.

  • Create a property on object state

    this.state = {
      contatos: []
    };
    
  • Create a method to add a new object in the contatos state and other methods to update these objects.

    // Método para adicionar novo objeto no estado "contatos"
    newContato = () => {
       let contatos = this.state.contatos;
       contatos.push({ nome: '', fone: '' });
       this.setState({ contatos: contatos });
    }
    
    // Método para atualizar o valor da propriedade "nome"
    // no objeto "N" do estado "contatos"
    // "i": índice, "e": event
    editNome = (i, e) =>  {
       let contatos = this.state.contatos;
       contatos[i].nome = e.target.value;
       this.setState({ contatos: contatos });
    }
    
    // Método para atualizar o valor da propriedade "fone"
    // no objeto "N" do estado "contatos"
    // "i": índice, "e": event
    editFone = (i, e) =>  {
       let contatos = this.state.contatos;
       contatos[i].fone = e.target.value;
       this.setState({ contatos: contatos });
    }
    
  • HTML Template

    {this.state.contatos.map((c, i) =>
    <div key={i}>
      <p>
        <label>#{i} - Nome</label>
        <input type="text" value={c.nome} onChange={e => this.editNome(i, e)} />
      </p>
      <p>
        <label>#{i} - Fone</label>
        <input type="text" value={c.fone} onChange={e => this.editFone(i, e)} />
      </p>
    </div>
    )}
    <button onClick={this.newContato}>Add Contato</button>
    
  • Note that adding a new object in the contatos state React automatically renders this new object on the screen without having to call the ReactDOM.render method again.

    Example running:

    class Contatos extends React.Component {
      constructor() {
        super();
        this.state = {
          contatos: []
        };
      }
    
      editNome = (i, e) => {
        let contatos = this.state.contatos;
        contatos[i].nome = e.target.value;
        this.setState({ contatos: contatos });
      }
    
      editFone = (i, e) => {
        let contatos = this.state.contatos;
        contatos[i].fone = e.target.value;
        this.setState({ contatos: contatos });
      }
    
      newContato = () => {
        let contatos = this.state.contatos;
        contatos.push({ nome: '', fone: '' });
        this.setState({ contatos: contatos });
      }
    
      render() {
        return (
          <div>
            <div className="esquerda">
            {this.state.contatos.map((c, i) =>
              <div key={i}>
                <p>
                  <label>#{i} - Nome</label>
                  <input type="text" value={c.nome} onChange={e => this.editNome(i, e)} />
                </p>
                <p>
                  <label>#{i} - Fone</label>
                  <input type="text" value={c.fone} onChange={e => this.editFone(i, e)} />
                </p>
              </div>
            )}
              <button onClick={this.newContato}>Add Contato</button>
            </div>
            <pre className="direita">
              <code>{JSON.stringify(this.state, null, 2)}</code>
            </pre>
          </div>
        );
      }
    }
    
    ReactDOM.render(<Contatos />, document.getElementById('root'));
    * {
      box-sizing: border-box;
    }
    body {
      margin: 0;
      padding: 0;
    }
    .esquerda,
    .direita {
      float: left;
      width: 50vw;
    }
    .esquerda > div {
      padding: 1em;
      padding-bottom: 0;
    }
    p, input {
      font-family: Lato;
    }
    p {
      margin: 0;
      margin-bottom: 10px;
    }
    label {
      display: block;
    }
    
    pre {
      background: #f3f3f3;
      padding: 1em;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="root"></div>

    References

    04.03.2018 / 00:12
    0

    The answer is simple, just read the documentation :

    constructor(){
         //Você tem de dizer quem é "this"
         this.insereRow = this.insereRow.bind(this);
    }
    
        
    20.03.2018 / 20:31