ReactJS with Array of Objects (searching character by character) - javascript

I'm new to Stackoverflow and ReactJS as well. I have the following code with 'array of objects' using a "textField" to filter 'array of objects'.
import React from 'react';
import NameItem from "./component/NameItem";
class App extends React.Component {
constructor(props) {
super(props)
this.state = { term: '', names = [{ name: 'Roony', about: 'He is a student'},{ name: 'Rocky', about: 'He is a player'},{ name: 'Ronny', about: 'He is a singer'}], filteredData:[{}] };
}
renderData(filteredData) {
if(filteredData) {
this.setState({names: filteredData});
}
return filteredData.map(item => <NameItem item={item}></NameItem>);
}
filterNames(namePass) {
const names = [{ name: 'Roony', about: 'He is a student'},{ name: 'Rocky', about: 'He is a player'},{ name: 'Ronny', about: 'He is a singer'}];
if(namePass && names) {
let filteredData = names.filter((item) => {
return item.toLowerCase().startsWith(namePass.toLowerCase())
});
console.log(filteredData);
this.setState({filteredData: filteredData});
if (filteredData) {
this.renderData(filteredData);
}
if (namePass === '') {
this.target(names);
}
}
}
render() {
return (
<>
<div>
<label>Search Person: </label>
<input type="text" value={this.state.name} id="searchEmp"
placeholder="Enter Person's Name"
onChange={(event) => {
this.setState({term: event.target.value});
// console.log(event.target.value);
this.filterNames(event.target.value);
}}/><br/>
</div>
<ul>
<NameItem item={this.state.names}></NameItem>
{
}
</ul>
</>
);
}
}
export default App;
I want result like when I start entering a character (for e.g I enter 'R') in "textField", all names starting from 'R' should get appear with all details and vice versa. A little more I want to set a whitespace as a invalid input when entered and then redirect to a window asking a user for input. I tried but as a beginner I'm getting error(s) one after another.
How can I filter this 'array of objects' to get my desired result ?

Use like this:
import React from 'react';
import "./styles.css";
export class App extends React.Component {
constructor(props) {
super(props)
this.state = {
term: '',
names : [
{ name: 'ARoony', about: 'He is a student'},
{ name: 'BRocky', about: 'He is a player'},
{ name: 'CRonny', about: 'He is a singer'}
],
filteredData:[{}]
};
}
render(){
return (
<div className="App">
<label>Search Person: </label>
<input
type="text"
value={this.state.name}
id="searchEmp"
placeholder="Enter Person's Name"
onChange={(event)=>this.setState({term: event.target.value})}
/>
<br/>
{this.state.names && this.state.names.filter(x=>x.name.toLowerCase().startsWith(this.state.term)).map(item=>{
return(<div className="data-body">
<div>{item.name}</div>
<div>{item.about}</div>
</div>
)
})
}
</div>
);
}
}
export default App;
DEMO

Related

Adding an Object to an Object's Array and setting the state in React

I am new at React and I come up with an Idea for learning many things in one shot. I have this component, Its initial state is an array with an object of baseball Players, I need to add new baseball Player's name through an Input field to the state and then, once a baseball Player is added, a second component appears with input fields to add data.
How can I do that?
export default class BaseballPlayerList extends React.Component {
constructor() {
super();
this.state = {
baseBallPlayers: [
{
name: "Barry Bonds",
seasons: [
{
year: 1994,
homeRuns: 37,
hitting: 0.294
},
{
year: 1996,
homeRuns: 40,
hitting: 0.294
}
]
}
]
};
this.addPlayer = this.addPlayer.bind(this);
}
addPlayer(e) {
e.preventDefault();
const newPLayer = {
baseBallPlayers: this.state.baseBallPlayers.name,
seasons: []
};
console.log(newPLayer);
this.setState(prevState => ({
baseBallPlayers: [...prevState.baseBallPlayers, newPlayer]
}));
}
render() {
return (
<div>
<div>
<ul>
{this.state.baseBallPlayers.map((player, idx) => (
<li key={idx}>
<PlayerSeasonInfo player={player} />
</li>
))}
</ul>
</div>
<input value={this.state.baseBallPlayers.name} />
<button onClick={this.addPlayer}>AddPlayer</button>
</div>
);
}
}
export default class PlayerSeasonInfo extends Component {
constructor(props) {
super(props);
this.player = this.props.player;
}
render() {
return (
<div>
{this.player && (
<div>
<span>{this.baseBallPlayers.name}</span>
<span>
<input placeholder="year" />
<input placeholder="homeRuns" />
<input placeholder="hitting" />
<button>AddInfo</button>
</span>
</div>
)}
</div>
);
}
}
here do you have a working example: https://codesandbox.io/s/nervous-yonath-9u2d6
the problem was where you where storing the new name and how you where updating the whole players state.
hope the example helps!

How to change DOM using onSubmit in React JS?

I am using react for the front end of a search application.
When user submits a query and a list of results pop up, each with a button that says "Learn More". When the "Learn More" button is pressed, the list of results should all disappear and be replaced with the information on that topic that was selected.
The search bar above should stay in place, if a user searches new information, the learn more info should go away and the new list of results should appear.
I am having trouble displaying the learn more information.
The biggest issue I am having is that I have to use the form with the onSubmit function and as soon as the onSubmit function is called my results will stay for a few seconds and then everything will disappear.
The following shows the parts of my file related to the issue
class Search extends React.Component {
learnMore(obj){
//Here is where i would like to replace the results class with the learn more info. obj.learnMore has the info stored
}
render() {
return (
<div className="search">
<div className="search-bar">
// Here is where my search bar is, results of search get added to results array
</div>
<div className= "results">
{this.state.results.map((obj) =>
<div key={obj.id}>
<p> {obj.name} </p>
<form id= "learn-more-form" onSubmit={() => {this.learnMore(obj); return false;}}>
<input type="submit" value="Learn More"/>
</form>
</div>
)}
</div>
</div>
);
}
}
There are many ways to handle this scenario. In this case, I recommend separating containers from components. The container will handle all things state and update its children components accordingly.
Please note that this example uses a lot of ES6 syntaxes. Please read the following to understand how some of it works: fat arrow functions, ES6 destruction, spread operator, ternary operator, class properties, a controlled react form utilizing event handlers and state, array filtering, and type checking with PropTypes.
It's a lot to take in, so if you have any questions, feel free to ask.
Working example:
containers/SeachForm
import React, { Component } from "react";
import moment from "moment";
import LearnMore from "../../components/LearnMore";
import Results from "../../components/Results";
import SearchBar from "../../components/Searchbar";
const data = [
{
id: "1",
name: "Bob",
age: 32,
email: "bob#example.com",
registered: moment("20111031", "YYYYMMDD").fromNow(),
description: "Bob is a stay at home dad."
},
{
id: "2",
name: "Jane",
age: 43,
email: "jane#example.com",
registered: moment("20010810", "YYYYMMDD").fromNow(),
description: "Jane is a CEO at Oracle."
},
{
id: "3",
name: "Yusef",
age: 21,
email: "yusef#example.com",
registered: moment("20180421", "YYYYMMDD").fromNow(),
description: "Yusef is a student at UC Berkeley."
},
{
id: "4",
name: "Dasha",
age: 29,
email: "dasha#example.com",
registered: moment("20050102", "YYYYMMDD").fromNow(),
description: "Dasha is an owner of a local antique shop."
},
{
id: "5",
name: "Polina",
age: 18,
email: "dasha#example.com",
registered: moment("20190102", "YYYYMMDD").fromNow(),
description: "Polina works at a local movie theather."
}
];
const initialState = {
searchQuery: "",
results: data, // <== change this to an empty array if you don't want to show initial user data
learnMore: false
};
class SearchForm extends Component {
state = { ...initialState }; // spreading out the initialState object defined above; it'll be the same as: "state = { searchQuery: "", results: data, learnMore: false }; "
handleSubmit = e => {
e.preventDefault(); // prevents a page refresh
if (!this.state.searchQuery) return null; // prevents empty search submissions
this.setState({
results: data.filter(
person => person.name.toLowerCase() === this.state.searchQuery.toLowerCase()
) // filters the dataset with the "searchQuery" (lowercased names) and returns the result if it finds a match
});
};
handleSearch = ({ target: { value } }) =>
this.setState({ searchQuery: value }); // updates searchQuery input with an event.target.value
handleReset = () => this.setState({ ...initialState }); // resets to initial state
handleLearnMore = person => {
this.setState({ learnMore: true, results: person }); // sets learnMore to true (to show the "LearnMore" component) and sets results to the selected user
};
render = () => (
<div className="container">
<SearchBar
handleReset={this.handleReset}
handleSearch={this.handleSearch}
handleSubmit={this.handleSubmit}
searchQuery={this.state.searchQuery}
/>
{!this.state.learnMore ? ( // if learnMore is false, then show "Results"
<Results
results={this.state.results}
handleLearnMore={this.handleLearnMore}
/>
) : (
<LearnMore {...this.state.results} /> // otherwise, show LearnMore
)}
</div>
);
}
export default SearchForm;
components/SearchBar
import React from "react";
import PropTypes from "prop-types";
const SearchBar = ({
handleReset,
handleSearch,
handleSubmit,
searchQuery
}) => (
<div className="search">
<div className="search-bar">
<form onSubmit={handleSubmit}>
<input
type="text"
className="uk-input"
value={searchQuery}
placeholder="Search for a name"
onChange={handleSearch}
/>
<div className="button-container">
<button
type="button"
className="uk-button uk-button-danger reset"
onClick={handleReset}
>
Reset
</button>
<button type="submit" className="uk-button uk-button-primary submit">
Submit
</button>
</div>
</form>
</div>
</div>
);
SearchBar.propTypes = {
handleReset: PropTypes.func.isRequired,
handleSearch: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
searchQuery: PropTypes.string
};
export default SearchBar;
components/Results
import React from "react";
import PropTypes from "prop-types";
const Results = ({ handleLearnMore, results }) => (
<div className="results">
{results && results.length > 0 ? (
results.map(person => (
<div key={person.id} className="uk-card uk-card-default uk-width-1-2#m">
<div className="uk-card-header">
<div className="uk-width-expand">
<h3 className="uk-card-title uk-margin-remove-bottom">
{person.name}
</h3>
</div>
</div>
<div className="uk-card-body">
<p>{person.description}</p>
</div>
<div className="uk-card-footer">
<button
onClick={() => handleLearnMore(person)}
className="uk-button uk-button-text"
>
Learn More
</button>
</div>
</div>
))
) : (
<div className="uk-placeholder">No users were found!</div>
)}
</div>
);
Results.propTypes = {
handleLearnMore: PropTypes.func.isRequired,
results: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string,
name: PropTypes.string,
age: PropTypes.number,
email: PropTypes.string,
registered: PropTypes.string,
description: PropTypes.string
})
)
};
export default Results;
components/LearnMore
import React from "react";
import PropTypes from "prop-types";
const LearnMore = ({ name, email, age, description, registered }) => (
<div className="uk-card uk-card-default uk-card-body">
<h3 className="uk-card-header">{name}</h3>
<p>
<strong>Email</strong>: {email}
</p>
<p>
<strong>Registered</strong>: {registered}
</p>
<p>
<strong>Age</strong>: {age}
</p>
<p>
<strong>Job</strong>: {description}
</p>
</div>
);
LearnMore.propTypes = {
name: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
registered: PropTypes.string.isRequired,
description: PropTypes.string.isRequired
};
export default LearnMore;
You should do your onSubmit like this:
<form id= "learn-more-form" onSubmit={this.learnMore(obj)}>
<input type="submit" value="Learn More"/>
</form>
Then the function should be:
learnMore = (data) => (e) => {
e.preventDefault()
console.log(data) // probably setState with this data so you can display it when it, like this.setState({ currentMoreResults: data })
}

How to render an array of objects in React?

could you please tell me how to render a list in react js.
I do like this
https://plnkr.co/edit/X9Ov5roJtTSk9YhqYUdp?p=preview
class First extends React.Component {
constructor (props){
super(props);
}
render() {
const data =[{"name":"test1"},{"name":"test2"}];
const listItems = data.map((d) => <li key={d.name}>{d.name}</li>;
return (
<div>
hello
</div>
);
}
}
You can do it in two ways:
First:
render() {
const data =[{"name":"test1"},{"name":"test2"}];
const listItems = data.map((d) => <li key={d.name}>{d.name}</li>);
return (
<div>
{listItems }
</div>
);
}
Second: Directly write the map function in the return
render() {
const data =[{"name":"test1"},{"name":"test2"}];
return (
<div>
{data.map(function(d, idx){
return (<li key={idx}>{d.name}</li>)
})}
</div>
);
}
https://facebook.github.io/react/docs/jsx-in-depth.html#javascript-expressions
You can pass any JavaScript expression as children, by enclosing it within {}. For example, these expressions are equivalent:
<MyComponent>foo</MyComponent>
<MyComponent>{'foo'}</MyComponent>
This is often useful for rendering a list of JSX expressions of arbitrary length. For example, this renders an HTML list:
function Item(props) {
return <li>{props.message}</li>;
}
function TodoList() {
const todos = ['finish doc', 'submit pr', 'nag dan to review'];
return (
<ul>
{todos.map((message) => <Item key={message} message={message} />)}
</ul>
);
}
class First extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [{name: 'bob'}, {name: 'chris'}],
};
}
render() {
return (
<ul>
{this.state.data.map(d => <li key={d.name}>{d.name}</li>)}
</ul>
);
}
}
ReactDOM.render(
<First />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Shubham's answer explains very well. This answer is addition to it as per to avoid some pitfalls and refactoring to a more readable syntax
Pitfall : There is common misconception in rendering array of objects especially if there is an update or delete action performed on data. Use case would be like deleting an item from table row. Sometimes when row which is expected to be deleted, does not get deleted and instead other row gets deleted.
To avoid this, use key prop in root element which is looped over in JSX tree of .map(). Also adding React's Fragment will avoid adding another element in between of ul and li when rendered via calling method.
state = {
userData: [
{ id: '1', name: 'Joe', user_type: 'Developer' },
{ id: '2', name: 'Hill', user_type: 'Designer' }
]
};
deleteUser = id => {
// delete operation to remove item
};
renderItems = () => {
const data = this.state.userData;
const mapRows = data.map((item, index) => (
<Fragment key={item.id}>
<li>
{/* Passing unique value to 'key' prop, eases process for virtual DOM to remove specific element and update HTML tree */}
<span>Name : {item.name}</span>
<span>User Type: {item.user_type}</span>
<button onClick={() => this.deleteUser(item.id)}>
Delete User
</button>
</li>
</Fragment>
));
return mapRows;
};
render() {
return <ul>{this.renderItems()}</ul>;
}
Important : Decision to use which value should we pass to key prop also matters as common way is to use index parameter provided by .map().
TLDR; But there's a drawback to it and avoid it as much as possible and use any unique id from data which is being iterated such as item.id. There's a good article on this - https://medium.com/#robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318
Try this below code in app.js file, easy to understand
function List({}) {
var nameList = [
{ id: "01", firstname: "Rahul", lastname: "Gulati" },
{ id: "02", firstname: "Ronak", lastname: "Gupta" },
{ id: "03", firstname: "Vaishali", lastname: "Kohli" },
{ id: "04", firstname: "Peter", lastname: "Sharma" }
];
const itemList = nameList.map((item) => (
<li>
{item.firstname} {item.lastname}
</li>
));
return (
<div>
<ol style={{ listStyleType: "none" }}>{itemList}</ol>
</div>
);
}
export default function App() {
return (
<div className="App">
<List />
</div>
);
}
import React from 'react';
class RentalHome extends React.Component{
constructor(){
super();
this.state = {
rentals:[{
_id: 1,
title: "Nice Shahghouse Biryani",
city: "Hyderabad",
category: "condo",
image: "http://via.placeholder.com/350x250",
numOfRooms: 4,
shared: true,
description: "Very nice apartment in center of the city.",
dailyPrice: 43
},
{
_id: 2,
title: "Modern apartment in center",
city: "Bangalore",
category: "apartment",
image: "http://via.placeholder.com/350x250",
numOfRooms: 1,
shared: false,
description: "Very nice apartment in center of the city.",
dailyPrice: 11
},
{
_id: 3,
title: "Old house in nature",
city: "Patna",
category: "house",
image: "http://via.placeholder.com/350x250",
numOfRooms: 5,
shared: true,
description: "Very nice apartment in center of the city.",
dailyPrice: 23
}]
}
}
render(){
const {rentals} = this.state;
return(
<div className="card-list">
<div className="container">
<h1 className="page-title">Your Home All Around the World</h1>
<div className="row">
{
rentals.map((rental)=>{
return(
<div key={rental._id} className="col-md-3">
<div className="card bwm-card">
<img
className="card-img-top"
src={rental.image}
alt={rental.title} />
<div className="card-body">
<h6 className="card-subtitle mb-0 text-muted">
{rental.shared} {rental.category} {rental.city}
</h6>
<h5 className="card-title big-font">
{rental.title}
</h5>
<p className="card-text">
${rental.dailyPrice} per Night ยท Free Cancelation
</p>
</div>
</div>
</div>
)
})
}
</div>
</div>
</div>
)
}
}
export default RentalHome;
Try this:
class First extends React.Component {
constructor (props){
super(props);
}
render() {
const data =[{"name":"test1"},{"name":"test2"}];
const listItems = data.map((d) => <li key={d.name}>{d.name}</li>;
return (
<div>
{listItems}
</div>
);
}
}

Reactjs with Pokeapi

I have an app that searches the name of the pokemon reads the data eg. name, height, weight. Now when it comes to the abilities I can't get the value of the name of the ability.
here's my app.js
import React, { Component } from 'react';
import './App.css';
import Request from 'superagent';
class App extends Component {
constructor(props) {
super(props);
this.state = {
body: "",
value: "",
name: "",
abilities: "",
order: "",
weight: "",
height: ""
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value.toLowerCase()});
}
handleSubmit(event) {
var url = "https://pokeapi.co/api/v2/pokemon/"+this.state.value;
Request.get(url).then((response) => {
this.setState({
body: response.body,
height: response.body.height,
weight: response.body.weight,
abilities: response.body.abilities,
name: response.body.name,
order: response.body.order,
picFront: response.body.sprites.front_default,
picBack: response.body.sprites.back_default,
picShiny: response.body.sprites.front_shiny,
});
});
event.preventDefault();
}
render() {
return (
<div className="flex">
<div className="App">
<h1>Search Pokemon</h1>
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.value} onChange={this.handleChange} />
<input type="submit" value="Submit" />
</form>
</div>
<div className="app2">
<h1><small>{this.state.order} </small>{this.state.name}</h1>
<img alt={this.state.name} src={this.state.picFront}/>
<img alt={this.state.name} src={this.state.picBack}/>
<img alt={this.state.name} src={this.state.picShiny}/>
<p>Height: {this.state.height}</p>
<p>Weight: {this.state.weight}</p>
<p>list of abilities here</p>
</div>
</div>
);
}
};
export default App;
Abilities has this structure. You can check this by logging this.state.abilities
abilities: [
{
slot: 3,
is_hidden: true,
ability: {
url: "https://pokeapi.co/api/v2/ability/31/",
name: "lightning-rod"
}
},
{
slot: 1,
is_hidden: false,
ability: {
url: "https://pokeapi.co/api/v2/ability/9/",
name: "static"
}
}
]
It's just an array. What you need to do is iterate over this array to retrieve those name values. There are a lot of ways to do this but the general logic should be something like:
"For each of these objects in the abilities array, I need to retrieve ability.name"
I am going to post some code here but try to solve it yourself before looking at mine.
In your p tag, you can do this
<p>
list of abilities here:
{this.state.abilities && this.state.abilities.map((abilityObject) =>
abilityObject.ability.name).join(', ')}
</p>

React form, to submit object which is then pushed to array

I'm new to React and unsure about how to do this.
I have an array of objects that I have mapped through and rendered in my view. What I want to do is set up a form that will submit the values of each field to the corresponding properties of a new object, but I'm not sure how to go about doing this.
Here is my initial data, which is rendered in the view:
contactArray = [
{
name: 'John'
email: 'john#email.com'
number: 111-111-111
},
{
name: 'Dave'
email: 'dave#email.com'
phone: '222-222-222'
}
]
Then I have a form:
class InputForm extends Component {
render() {
return (
<form>
<input type='text' onChange={this.handleChange}/>
<input type='text' onChange={this.handleChange}/>
<input type='text' onChange={this.handleChange}/>
<button type='submit' onSubmit={this.handleSubmit}>SUBMIT</button>
</form>
)
}
Then I assume I declare the state as this:
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
phone: ''
}
}
Then the submission function I don't really know how to handle...
handleSubmit() {
// not sure about this...
this.setState({
name: // ????
email: // ????
phone: // ????
})
}
And then I want to clear the submit form, as well as the object that is used to push the new object, which is now in the array (I hope that makes sense...)
So, I'm not even sure how to use state in this scenario, but ultimately I want to push() the new object to the array that is rendered, with all the properties as they were completed in the form.
Sorry I can't be more complete with my working up to this point, but would at least appreciate some pointers on this!
From what I understand you want to push new people to the existing contactArray ? I will share with my way of doing it. Have a look:
const contactArray = [
{
name: 'John',
email: 'john#email.com',
phone: '111-111-111'
},
{
name: 'Dave',
email: 'dave#email.com',
phone: '222-222-222'
}
];
class Form extends React.Component {
constructor() {
super();
this.state = {
contacts: contactArray
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
const
{ contacts } = this.state,
name = this.refs.name.value,
email = this.refs.email.value,
phone = this.refs.phone.value;
this.setState({
contacts: [...contacts, {
name,
email,
phone
}]
}, () => {
this.refs.name.value = '';
this.refs.email.value = '';
this.refs.phone.value = '';
});
}
render() {
const { contacts } = this.state;
console.log('message',this.state.contacts);
return (
<div>
<h2>Add Someone</h2>
<form onSubmit={this.handleSubmit}>
<input type="text" ref="name" placeholder="name" />
<input type="text" ref="email" placeholder="email" />
<input type="text" ref="phone" placeholder="phone" />
<button type="submit">Submit</button>
</form>
<h2>Exsiting contacts:</h2>
<ul>
{contacts.map((contact) =>
<li>{`Name: ${contact.name} Email: ${contact.email} Phone: ${contact.phone}`}</li>
)}
</ul>
</div>
)
}
}
ReactDOM.render(<Form />, document.getElementById('root'));
So first thing we do is save contactArray within our actual component where we are going to use it, next we decalre and bind our handleSubmit I am using refs for the inputs in order to get thier value. this.setState ({ contacts: [...contacts] , { Object }); Here we use the ES6 spread operator to pass all the existing contacts to our new state and add a new contact. { name, email, phone } Is exactly like doing { name:name, email:email ...} It's just a short-hand, this.setState({}, () => { Callback! }); In the callback function of this.setState({}); I am going to clear the input values. Live demo: http://codepen.io/ilanus/pen/qaXNmb
Here is another way you can do it, same results different approach.
const contactArray = [
{
name: 'John',
email: 'john#email.com',
phone: '111-111-111'
},
{
name: 'Dave',
email: 'dave#email.com',
phone: '222-222-222'
}
];
class Form extends React.Component {
constructor() {
super();
this.state = {
contacts: contactArray,
newContact: {
name: '',
email: '',
phone: ''
}
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleInput = this.handleInput.bind(this);
}
handleSubmit(e) {
e.preventDefault();
const { contacts, newContact } = this.state;
this.setState({
contacts: [...contacts, newContact],
}, () => {
for (let val in newContact) {
newContact[val] = ''; // Clear the values...
}
this.setState({ newContact });
});
}
handleInput(e, element) {
const { newContact } = this.state;
newContact[element] = e.target.value;
this.setState({ newContact });
}
render() {
const { contacts, newContact } = this.state;
const { name, email, phone } = newContact;
return (
<div>
<h2>Add Someone</h2>
<form onSubmit={this.handleSubmit}>
<input type="text" value={name} onChange={e => this.handleInput(e, 'name')} placeholder="name" />
<input type="text" value={email} onChange={e => this.handleInput(e, 'email')} placeholder="email" />
<input type="text" value={phone} onChange={e => this.handleInput(e, 'phone')} placeholder="phone" />
<button type="submit">Submit</button>
</form>
<h2>Exsiting contacts:</h2>
<ul>
{contacts.map((contact) =>
<li>{`Name: ${contact.name} Email: ${contact.email} Phone: ${contact.phone}`}</li>
)}
</ul>
</div>
)
}
}
ReactDOM.render(<Form />, document.getElementById('root'));
Live demo: http://codepen.io/ilanus/pen/LRjkgx
I highly recommend using the first example. as it's performance will be better :)
You don't need to set state for all the inputs. If you do, it'll be a problem when you have more input fields. See the below fiddle, in that, I've used a single state to store the entire contacts. When you press the submit button, it get all the values from the input and save it to the state. Hope it helps!
Fiddle: http://jsfiddle.net/Pranesh456/8u4uz5xj/1/
[UPDATE]
e.value = null will clear the value inside the form. By this, you'll able to reset the entire form.
slice() is used to make a copy of the array in the state. As assignment of array is a reference to the original array, any operation on the new array will also reflect in the original array.
Example:
a = [1,2,4]
b = a
b.push(7)
console.log(b) //prints [1,2,4,7]
console.log(a) //also prints [1,2,4,7]
But
b = a.slice() //creates a copy of a
b.push(7)
console.log(b) //prints [1,2,4,7]
console.log(a) //also prints [1,2,4]
More details about slice
By doing this, you'll not mutate the existing state, which is a good practice.
Hope it help!!

Categories

Resources