2

I know how to create a list of names using one input text field. How do I create a list of people with an input field of first name and an input field of last name. Thus, how do you create a list of people using multiple input values which consist of last name and first name. How do I do this in react.js?

  • John Carter
  • Adam West
  • Mark Hamill
  • Stan Lee
  • Peter Parker
  • Clark Kent

Right now, I only now how to create a list like the following using only one input field:

  • John
  • Adam
  • Mark
  • Stan
  • Peter
  • Clark

The dots before each name is not necessary at this point.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

function PostButton(props){
    var style = {
        width:24,
        height:24
    }
    return (
        <button style = {style} onClick = { () => props.handleClick()}>{props.label}</button>
    )
}
function PostText(props){
    var style = {
        border:"1px solid black",
        width: props.width
    }
    return (
        <div style = {style}>{props.text}</div>
    )
}
function Post(props){
    var style = {
        display:"flex"
    }
    return (
        <div style = {style}>
            <PostButton label = "x" handleClick = {props.removeItem}/>
            <PostTextFirstName text = {props.firstName} width = "200"/>
            <PostTextLastName text = {props.lastName} width = "200" />
        </div>
    )
}

function PostList(props){
    return (
        <ol>
        {
            props.postList.map((item,index) => 
                <Post key = {index} 
                      firstName = {item.firstName} 
                      lastName = {item.lastName}
                      removeItem = {() => props.removeItem(index)}
                />
             )
         }
        </ol>
    )  
}

class App extends React.Component{
    constructor(props){
        super(props)
        this.state = {value:"", items : []}
    } 
    handleChange(event){
        this.setState({value:event.target.value})
        console.log(this.state.value)
    }
    addItem()
    {
        var itemsCopy = this.state.items.slice()
        var truncatedString = this.state.value.substring(0,20);
        itemsCopy.push({"firstName":truncatedString})
        this.setState({items:itemsCopy,value:""})
    }
    removeItem(index)
    {
        var itemsCopy = this.state.items.slice()
        itemsCopy.splice(index,1);
    
        this.setState({items:itemsCopy})
    }
    render(){
        return (
            <div>
                <div>First Name</div>
                <input value = {this.state.value} onChange = {this.handleChange.bind(this)}/>
                <div>Last Name</div>
                <input value = {this.state.value} onChange = {this.handleChange.bind(this)}/>
                <button onClick = { () => this.addItem()}>Submit</button>
                <PostList postList = {this.state.items} 
                          removeItem = {this.removeItem.bind(this)}
                />
            </div>
        )
    }
}

ReactDOM.render(
    <App/>,
    document.getElementById("root")
)

3
  • Not sure I understand your question. Do you want to create a list of persons (first name + last name) based on successive submits of your form, or do you want to be able to append new pairs of first name / last name input fields to your form? Commented Jan 9, 2018 at 6:39
  • I added more details to the question. I know how to add the first name via a single input field and build up a list of first names. How do I build up a list of people with their first name and last name using an input field of first name and input field of last name. I only know how to use one input field. I don't know how to do it with two input fields. I need to build a list of people with their first and last names, not just their first name. Commented Jan 9, 2018 at 6:42
  • One simple search: stackoverflow.com/questions/35965275/… Commented Jan 9, 2018 at 7:05

1 Answer 1

1

You have the general principle down right, your big mistake here is to handle two separate text fields with one single state variable. Obviously, when you do that, you will overwrite the first name when setting the last name and vice-versa.

Here are the changes you need to make:

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      firstname: "",
      lastname: "",
      items: []
    };
  }

  handleChange(event) {
    if (event.target.name === "firstname") {
      this.setState({ firstname: event.target.value });
    } else if (event.target.name === "lastname") {
      this.setState({ lastname: event.target.value });
    }
  }

  addItem() {
    this.setState({
      items: [ 
        ...this.state.items, 
        {
          firstName: this.state.firstname,
          lastName: this.state.lastname
        }
      ],
      firstname: "",
      lastname: ""
    });
  }

  removeItem(index) {
    const items = this.state.items.filter((e, idx) => idx !== index); 
    this.setState({ items });
  }

  render() {
    return (
      <div>
        <div>First Name</div>
        <input
          name="firstname"
          value={this.state.firstname}
          onChange={this.handleChange.bind(this)} />
        <div>Last Name</div>
        <input
          name="lastname"
          value={this.state.lastname}
          onChange={this.handleChange.bind(this)} />
        <button onClick={() => this.addItem()}>Submit</button>
        <PostList
          postList={this.state.items}
          removeItem={this.removeItem.bind(this)} />
      </div>
    );
  }
}

Note that I use the name attribute of each input to decide which corresponding variable to change in the state. Another possibility would have been to create 2 different functions, one to handle the firstName text changes, the other to handle the lastName text changes.

I've also simplified your addItem and removeItem methods, using a bit of ES6 syntax.

As you can see, the approach is the same one you had, save for the separate handling of first name and last name.

Here is a CodeSandbox with all pieces put together.

Sign up to request clarification or add additional context in comments.

3 Comments

Just wondering why my previous functions like PostButton were converted to const.
What is the difference between import ReactDOM from 'react-dom'; vs import { render } from 'react-dom';
The conversion of PostButton from a function to a const assigned an 'arrow' function is just using ES6 syntax, but there's no real difference in behavior. There's also no difference between import ReactDOM from 'react-dom'; and then using ReactDOM.render(); and import { render } from 'react-dom'; and then using render();. In one case we import an entire module and then used a named method from that module, in the other we directly import the named method, but the end result is strictly identical.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.