Reputation:
I'm a reactJS newbie and I'm practising by creating a simple example that the expected result is, each input value (separated by whitespace) inserted in an HTML element (<h1>
). What it executed instead is each output value disappears when it's being separated by space. It's much better to copy-paste the code below on your own project to understand exactly what I mean.
import React from 'react';
class Items extends React.Component {
constructor() {
super();
this.state = {
result: ''
}
this.showItems = this.showItems.bind(this);
}
render() {
let results = this.state.result,
resultItem = [];
for(var i=0; i<results.length; i++) {
resultItem = results[i];
}
return(
<div>
/* Example, the user typed "Item1 Item2 Item3" */
<input type='text' placeholder='Enter items' onChange={this.showItems} />
<div className='result'>
<h1>{resultItem}</h1>
/*
Here, the displayed result should be:
<h1>Item1</h1>
<h1>Item2</h1>
<h1>Item3</h1>
*/
</div>
</div>
);
}
itemsResult(result) {
this.setState({result});
}
showItems(e) {
const items = e.target.value.split(' ');
this.itemsResult(items);
}
}
export default Items;
How can I fix this?
Upvotes: 1
Views: 60
Reputation: 281676
You need to map over the array that you create after splitting by space
class Items extends React.Component {
constructor() {
super();
this.state = {
result: []
}
this.showItems = this.showItems.bind(this);
}
render() {
return(
<div>
<input type='text' placeholder='Enter items' onChange={this.showItems} />
<div className='result'>
{this.state.result.length > 0 && this.state.result.map(function(item , index){
return <h1 key={index}>{item}</h1>
})}
</div>
</div>
);
}
itemsResult (result) {
console.log(result)
this.setState({result});
}
showItems(e) {
const items = e.target.value.split(' ');
this.itemsResult(items);
}
}
ReactDOM.render(<Items/>, document.getElementById('app'));
<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="app"></div>
Upvotes: 1
Reputation: 12093
Your Mistake is , in loop you are assigning last value to resultItem
. You need to push data to resultItem using array push()
method. Everything else seems good. Better way is to use .map()
instead of for loop
resultItem = [];
for(var i=0; i<results.length; i++) {
resultItem = results[i];//You are assigning resultItem only last value
}
Should Be:
resultItem = [];
for(var i=0; i<results.length; i++) {
resultItem.push(<h1 key={i}>{results[i]}</h1>);
}
USING .map() Method:
<div className='result'>
{this.state.result.length>0 && this.state.result.map(function(item , index){
return <h1 key={index}>{item}</h1>
})}
Upvotes: 1
Reputation: 1098
Two things in your code are problematic.
You're reassigning resultItem
every time in the for
loop. See:
resultItem = results[i];
After the for
loop ends, resultItem
will only contain the last element of results
.
You're rendering an array of strings directly within a <h1>
element. See:
<h1>{resultItem}</h1>
React can understand what to do with arrays, but it'll only render the items one after the other. You should include the h1
tags within the array themselves. Idiomatic way to do it is to use Array#map
:
// ...
{
resultItem.map(str => <h1>str</h1>)
}
// ...
By the way, your resultItem
variable looks extraneous. Just render results
instead, you're basically just making a copy of it for resultItem
anyway.
Upvotes: 0
Reputation: 104379
Use this:
class Items extends React.Component {
constructor() {
super();
this.state = {
result: ''
}
this.showItems = this.showItems.bind(this);
}
showItems(e) {
const items = e.target.value;
this.setState({result: items});
}
renderValues(){
let data = this.state.result;
return data.split(' ').map((el, i) => <h1 key={i}>{el}</h1>)
}
render() {
return(
<div>
<input type='text' placeholder='Enter items' onChange={this.showItems} />
<div className='result'>
{this.renderValues()}
</div>
</div>
);
}
}
ReactDOM.render(<Items/>, document.getElementById('app'))
<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='app'/>
Upvotes: 0
Reputation: 1926
Problem is with your for loop. It should be:
for(var i=0; i<results.length; i++) {
resultItem.push(results[i]);
}
or if you want to create a separate tag for each item, you can do:
const list = resultItems.map((item) => <p>{item}</p>)
Note:
May be you can create a listitems. You should not have multiple h1. Also, comments does not work in the render section. So you should remove that.
Upvotes: 0