I think I've wrapped brackets properly but I am still getting an error:
Uncaught Error: Parse Error: Line 22: Unexpected token if
if(this.state.isEditing) {
^
Here's a JSFiddle
Relevant code
...
renderItem(){
return (
if(this.state.isEditing) {
<input type="text" />
<button>Save</button>
} else {
this.state.items.map((item, i) =>
<li key={i}>
{item}
<button>Edit</button>
<button onClick={this.dlt_item.bind(this, i)}>Delete</button>
</li>
)
}
)
},
...
You cannot have an if-else statement in a return function. Also You can also make use of ternary operators instead of if-else. Also I would recommend you do have a go at some of the basic react tutorials that will get you basics clear on some of the important syntax's
Also React clearly tells you what the error is. Just search for that error and you can easily find your problem. Also you should first try to see where exacty the error points at and then debug with a proper method. Hope this helps and you can debug the rest of the errors on your own.
Do it this way
renderItem(){
var renderIt = null;
if(this.state.isEditing){
renderIt = <div><input type="text" />
<button>Save</button></div>
}else{
renderIt = this.state.items.map((item,i)=> <li key={i}>{item}
<button>Edit</button>
<button onClick={this.dlt_item.bind(this,i)}>Delete</button>
</li>
)
}
return (
<div>{renderIt}</div>
)
},
JSFIDDLE
var App = React.createClass({
getInitialState(){
return {
items:[1,2,3],
isEditing:false
}
},
dlt_item(key){
var newItems = this.state.items.filter((item,i)=> i !== key)
this.setState({items:newItems})
},
edit_handler(){
this.setState({isEditing:true})
},
isEditing_html(){
return(
<div>
<input type="text" />
<button>Save</button>
</div>
)
},
renderItem(){
return(
this.state.items.map(function(item,i) {
var temp = null;
if(this.state.isEditing){
temp = this.isEditing_html()
}else{
temp = <div><button>Edit</button>
<button onClick={this.dlt_item.bind(this,i)}>Delete</button></div>
}
return (<li key={i}>{item}
{temp}
</li>
)
}.bind(this)
)
)
},
render(){
return(
<ul>
{this.renderItem()}
</ul>
)
}
})
ReactDOM.render(<App />, document.getElementById('container'));
JSFIDDLE
It's because you're doing an if statement inside a return block. Try a format like this:
renderItem() {
if(this.state.isEditing) {
return (
<div>Editing</div>
);
} else {
return (
<div>Default</div>
);
}
}
Related
I'm trying to do conditional rendering in React (only maps and renders when props exist).
render() {
if (this.props.res) {
return(
<div>{this.props.res.map(item => <li key={item.id}>{item.subreddit}</li>}</div>
)
} else {
return null
}
}
But I have this error:
Parsing error: Unexpected token, expected ","
Why is that, and how can I fix it? Or in another way, is there a better way to achieve my purpose?
There is syntax error, map(...) doesn't have closing parenthesis.
It should be:
<div>{this.props.res.map(item => <li key={item.id}>{item.subreddit}</li>)}</div>
Here are the issues I see:
map is missing the closing parenthesis
check the array length (an empty array will return true otherwise)
list items should be wrapped with an appropriate tag, such as <ul/>
render() {
const { res } = this.props;
return !res.length ? null : (
<ul>{res.map(item => <li key={item.id}>{item.subreddit}</li>)}</ul>
);
}
there was a brace missing in the end of the map.
render() {
return (
<div>
{
this.props.res && this.props.res.map(item => (
<li key={item.id}>{item.subreddit}</li>
))
}
</div>
);
}
render() {
if (this.props.res) {
return (
<div>
{this.props.res.map(item => (
<li key={item.id}>{item.subreddit}</li>
))}
</div>
);
} else {
return null;
}
}
I couldn't understand why...here is the GitHub repository: https://github.com/Dronrom/React-test
That’s because you initialized peopleList as null in your component. So map works only on arrays so you need to check peopleList whether its really an array before doing map on it so
Change
renderItems(arr) {
return arr.map(({id, name}) => {
return (
<li className="list-group-item"
key={id}
onClick={() => this.props.onItemSelected(id)}>
{name}
</li>
);
});
}
To
renderItems(arr) {
if(arr){
return arr.map(({id, name}) => {
return (
<li className="list-group-item"
key={id}
onClick={() => this.props.onItemSelected(id)}>
{name}
</li>
);
});
}
}
I think your issue may be that react renders once before componentDidMount(). This is an issue because your calling map on arr which is null. const { peopleList } = this.state; you set people list to your current state which you set as default to be null, state = {peopleList: null}; then you later call this.renderItems(peopleList); which people list is still null at this moment so you are getting the Cannot read property 'map' of null error.
I belive something like componentWillMount is what you need instead. I recommend looking at this post which has a similar issue of react life cycle methods. React render() is being called before componentDidMount()
the answer is very simple: the type of the input isn't array type, it might be null or undefined. so that it doesn't have .map function.
How to fix:
Make sure your input must be array type before call renderItems().
render(){
const { peopleList } = this.state;
const items = (peopleList && peopleList.length) ? this.renderItems(peopleList) : null;
return(
<ul className="item-list list-group">
{items}
</ul>
);
}
Or:
Make sure your input must be array type before do mapping:
renderItems(arr) {
return !arr ? null : arr.map(({id, name}) => {
return (
<li className="list-group-item"
key={id}
onClick={() => this.props.onItemSelected(id)}>
{name}
</li>
);
});
{product.size?.map(c=>(
<FilterSizeOption key={c}>{c}</FilterSizeOption>
))}
Wrapping the return statement with a if statement worked for me
So changed
return (
<div>
<Navbar />
{countries.map((country, i) => {
return (
<div>
<span key={`${country.name.common}${i}`}>
{country.name.common}
</span>
</div>
);
})}
</div>
);
to this
if (countries) {
return (
<div>
<Navbar />
{countries.map((country, i) => {
return (
<div>
<span key={`${country.name.common}${i}`}>
{country.name.common}
</span>
</div>
);
})}
</div>
);
}
Is there anything wrong with my code below?
render(){
return (
var users= this.state.users.map(user =>
<li key={user.id}>user.name</li>
)
<ul>{users}</ul>
)
}
I get error: unexpected token.
render() should return only a single element:
render(){
return (
<ul>
{
this.state.users.map(user => (
<li key={user.id}>{user.name}</li>
)
}
</ul>
);
}
It is not clear what you're returning in your code. Either do all logic above your return call, as shown below, or do like Ori Drori does in their answer.
render() {
var users= this.state.users.map(user =>
<li key={user.id}>{user.name}</li>
);
return <ul>{users}</ul>;
}
}
I do console.log(items) I got ['a','b','c'] but I got error of map is not a function.
..
var Todo_list = React.createClass({
getInitialState(){
return { items:['a','b']}
},
addItem(item){
this.setState({items:this.state.items.push(item)})
console.log(this.state.items) // this is working
},
render() {
return (
<div>
<TodoInput addItem={this.addItem} />
{this.state.items.map((item,i) => <li key={i}>{item}</li> )}
</div>
);
}
});
..
https://jsfiddle.net/tehwajh2/ Try to add an item, I wonder why, I guess I've pushed it correctly?
In this case you can use .concat instead of .push, because .push returns the new length of the array., length is Number, and Number does not have .map method that's why you get error
this.setState({ items: this.state.items.concat(item) })
Example
The push() method adds one or more elements to the end of an array and
returns the new length of the array.
The concat() method returns a new array comprised of the array on
which it is called joined with the array(s) and/or value(s) provided
as arguments.
You can try adding this.state.items.push(item); seperately. It works
var TodoInput = React.createClass({
handleAddItem(){
var todo_val = this.refs.todo_val.value;
this.props.addItem(todo_val);
},
render() {
return (
<div>
<input ref='todo_val' type="text" />
<button onClick={this.handleAddItem}>Add</button>
</div>
);
}
});
var Todo_list = React.createClass({
getInitialState(){
return { items:['a','b']}
},
addItem(item){
console.log(item);
this.state.items.push(item);
this.setState({items: this.state.items});
console.log(this.state.items)
},
render() {
return (
<div>
<TodoInput addItem={this.addItem} />
{this.state.items.map(function(item, key) {
return (
<li key={key}> {item}</li>
)
})}
</div>
);
}
});
ReactDOM.render(
<div>
<Todo_list />
</div>,
document.getElementById('container')
);
JSFIDDLE
Trying to create a li in react but failed. Error is near the map(), I got error of i is not defined, why?
const TodoItems = React.creatClass({
getInitialState() {
return {
items : [
{id:1,name:"Gym"},
{id:2,name:"Jump"},
{id:3,name:"Racing"}
]
}
},
renderItem(){
return(
<ul>
this.state.items.map(item,i =>
<li key={i}>item.name</li>
)
</ul>
)
},
render(){
return (
<renderItem />
)
}
})
When you have multiple arguments for an arrow function, you need to put () around them. So:
this.state.items.map((item,i) =>
// ------------------^------^
<li key={i}>item.name</li>
)
Your original code calls map with item as its first argument, and an arrow function taking a single argument (i) as its second argument.
You also need to put item.name in {} and put the call to map in {}:
renderItem(){
return(
<ul>
{this.state.items.map((item,i) =>
<li key={i}>{item.name}</li>
)}
</ul>
)
Then it works:
const { Component } = React;
const { render } = ReactDOM;
const TodoItems = React.createClass({
getInitialState() {
return {
items : [
{id:1,name:"Gym"},
{id:2,name:"Jump"},
{id:3,name:"Racing"}
]
}
},
renderItem(){
return(
<ul>
{this.state.items.map((item,i) =>
<li key={i}>{item.name}</li>
)}
</ul>
)
},
render(){
return this.renderItem();
}
});
render(<TodoItems /> , document.getElementById('items'));
<div id="items"></div>
<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>
That became clear to me when I used Babel's REPL to compile the JSX and realized I was seeing "this.state.map((item,i) =>" as a string.
try this :
renderItem(){
return(
<ul>
{this.state.items.map((item,i) => {
return(
<li key={i}>item.name</li>);
})}
</ul>
)