sasha romanov
sasha romanov

Reputation: 485

How to create element on button click?

I'm trying to create element for example and tried to use jquery it works with jquery but how to use only reactjs

$("#myButton").on("click", function() {
      $("#container").append('<div> <
        label > enter name < /label> <
        input onChange = {
          this.onInputChange
        }
        type = "text"
        placeholder = "what's your name" / >
        <
        /div>');
      });
<div>
  <label>enter name</label>
  <input onChange={this.onInputChange} type="text" placeholder="what's your name" />
</div>

I don't want to use some state tricks like true show element , false don't show. what if i want to show infinite elements of the div above not one or even 10.

I've tried using this a callback function that will try to use React.createElement() method

React.createElement("div", null, React.createElement("label", null, "enter name"), React.createElement("input", {
      onChange: this.onInputChange,
      type: "text",
      placeholder: "what's your name"
    }));

The expected result is on button Click i use react and only reactjs to create element and append it in the parent div.

Upvotes: 0

Views: 3411

Answers (1)

Cat_Enthusiast
Cat_Enthusiast

Reputation: 15688

Essentially, you should still use state for the ability to keep track of controlled-inputs, especially if you plan on creating multiple input tags with a click of a button.

Consider this sandbox here: https://codesandbox.io/s/angry-taussig-c81dm

Working code:

import React from "react";
import ReactDOM from "react-dom";
import uuid from "uuid";

import "./styles.css";

class App extends React.Component {
  state = {
    items: [{ id: uuid(), text: "" }]
  };

  addListItem = () => {
    const newItem = { id: uuid(), text: "" };
    this.setState({
      items: [...this.state.items, newItem]
    });
  };

  onInputChange = e => {
    const { id, value } = e.target;

    const newArr = this.state.items.map(item => {
      if (item.id == id) {
        return {
          ...item,
          text: value
        };
      } else {
        return item;
      }
    });

    this.setState({
      items: newArr
    });
  };

  createList = () => {
    const { items } = this.state;
    return items.map(item => {
      return (
        <div>
          <label>enter name</label>
          <input
            id={item.id}
            onChange={this.onInputChange}
            type="text"
            placeholder="what's your name"
            value={item.text}
          />
        </div>
      );
    });
  };

  render() {
    return (
      <div>
        {this.createList()}
        <button onClick={this.addListItem}>Add</button>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Notes:

  • state.items just keeps track of all the inputs you have created. Each input contains an id and a text value.
  • createList() generates your divs by iterating over the state list items. The inputs are controlled, meaning they correspond with a value in our state. (An object with the same id).
  • onInputChange() is needed to pass the event values to the right object in the list.

Ultimately this is used to maximize the capabilities of JSX and its relationship with component-state, versus forcefully creating uncontrolled elements.

Upvotes: 2

Related Questions