Reputation: 2204
Trying to create an editable inline textarea
. When this.state.showTextAreaEdit
isfalse
I display
<span>
<textarea> {todo.title} </ textarea>
<button> Save </button>
</span>
otherwise, I display:
<span>
{todo.title}
<button onClick={this.displayEdit}> Edit </button>
</span>
Demo here: https://stackblitz.com/edit/react-yoevt8
The problem displays nothing. There are no errors in the console.
class App extends Component {
constructor() {
super();
this.state = {
todos: [],
showTextAreaEdit: false
};
}
componentDidMount() {
this.getTodos();
}
displayEdit = () => {
this.setState({
showTextAreaEdit: true
})
}
getTodos = () => {
axios({
url: 'https://jsonplaceholder.typicode.com/todos',
method: 'GET'
})
.then(res => {
this.setState({
todos: res.data
});
})
.catch(error => {
console.log(error);
});
};
render() {
return (
<ul>
{this.state.todos.map((todo, index) => {
return
<li key={todo.id}>
{this.state.showTextAreaEdit ?
<span>
<textarea>{todo.title}</textarea>
<button>Save</button>
</span>
:
<span>
{todo.title}
<button onClick={this.displayEdit}>Edit</button>
</span>
}
</li>
})}
</ul>
);
}
}
Upvotes: 1
Views: 97
Reputation: 851
just replace your code with this one :-
what i did is that i took an new parameter on state which contain the id of selected list item and initially it is null when you click edit i pass the id on function and change its value to the id provided in the function.
and i also replace your condition. in this i check if the selected id matches the id of list item it show textarea field otherwise just simple text
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
import axios from 'axios';
class App extends Component {
constructor() {
super();
this.state = {
todos: [],
showTextAreaEdit: false,
editableTextArea:null
};
}
componentDidMount() {
this.getTodos();
}
displayEdit = (id) => {
this.setState({
editableTextArea: id
})
}
getTodos = () => {
axios({
url: 'https://jsonplaceholder.typicode.com/todos',
method: 'GET'
})
.then(res => {
this.setState({
todos: res.data
});
})
.catch(error => {
console.log(error);
});
};
render() {
return (
<ul>
{this.state.todos.map((todo, index) => {
return <li key={todo.id}>
{this.state.editableTextArea == todo.id ?
<span>
<textarea>{todo.title}</textarea>
<button>Save</button>
</span>
:
<span>
{todo.title}
<button onClick={()=>{this.displayEdit(todo.id)}}>Edit</button>
</span>
}
</li>
})}
</ul>
);
}
}
render(<App />, document.getElementById('root'));
it works great within your demo enjoy the code
Upvotes: 0
Reputation: 530
It's because the return statement doesn't find anything to return. Don't put enter after return statement. Try this
{this.state.todos.map((todo, index) => {
return (<li key={todo.id}>
{this.state.showTextAreaEdit ?
<span>
<textarea>{todo.title}</textarea>
<button>Save</button>
</span>
:
<span>
{todo.title}
<button onClick={this.displayEdit}>Edit</button>
</span>
}
</li>)
})}
Upvotes: 1
Reputation: 9681
Since your return has multiple lines, you will need to wrap it in brackets:
{this.state.todos.map((todo, index) => {
return ( // HERE
<li key={todo.id}>
{this.state.showTextAreaEdit ?
<span>
<textarea>{todo.title}</textarea>
<button>Save</button>
</span>
:
<span>
{todo.title}
<button onClick={this.displayEdit}>Edit</button>
</span>
}
</li>
)
}
Upvotes: 1
Reputation: 1143
{this.state.todos.map((todo, index) =>
<li key={todo.id}>
{this.state.showTextAreaEdit ?
<span>
<textarea>{todo.title}</textarea>
<button>Save</button>
</span>
:
<span>
{todo.title}
<button onClick={this.displayEdit}>Edit</button>
</span>
}
</li>
)}
remove return in your map funtion at render
Upvotes: 0