admin管理员组文章数量:1025822
How can I update isSelected
to true for the item that the user clicks on?
Here is my handleSelect
function so far:
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val, index) => {
//val.isSelected = index === true;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
This function is passed down correctly via props and is working, the issue I'm having is with the logic.
The current logic sets all items in the array to true which is incorrect. I only want to update / toggle the state of the item the user clicked.
I have an array of objects within state, here is what one of the objects looks like:
state = {
allGenres: [
{
id: 1,
genreTitle: 'Horror',
isSelected: false,
}
]
}
How can I update isSelected
to true for the item that the user clicks on?
Here is my handleSelect
function so far:
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val, index) => {
//val.isSelected = index === true;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
This function is passed down correctly via props and is working, the issue I'm having is with the logic.
The current logic sets all items in the array to true which is incorrect. I only want to update / toggle the state of the item the user clicked.
I have an array of objects within state, here is what one of the objects looks like:
state = {
allGenres: [
{
id: 1,
genreTitle: 'Horror',
isSelected: false,
}
]
}
Share
Improve this question
asked Jun 1, 2018 at 10:25
FilthFilth
3,22815 gold badges55 silver badges83 bronze badges
1
-
the
i
passed tohandleSelect
refers to what ? The index in thegenres
array or theid
of the genre, or something else ? – Gabriele Petrioli Commented Jun 1, 2018 at 10:57
4 Answers
Reset to default 2Here's how we can do it:
- On each clicked Genre, we get its
id
. - After we have the
id
, then we toggle the selected genreisSelected
flag. - Please follow
updateGenres
method, to check how we did it in an immutable way.
updateGenres(selectedId) {
const { allGenres } = this.state
this.setState({
// Here we make sure we don't mutate the state
allGenres: allGenres.map(genre => ({
...genre,
// Toggle the clicked one, and reset all others to be `false`.
isSelected: genre.id === selectedId
// If you want to keep the values of the rest genres, then the check should be:
// isSelected: (genre.id === selectedId) ? !genre.isSelected : genre.isSelected
}))
})
}
renderGenres() {
const { allGenres } = this.state
return allGenres.map(genre => <Gengre onClick={() => this.updateGenres(genre.id) })
}
render() {
return <div>{this.renderGenres()}</div>
}
The benefit of this approach is that you don't depend on the index
of the allGenres
and your toggle implementation will be decoupled to the presentation. Imagine if you change the genres sort (from ASC to DESC), then you have to change your toggle logic too.
Easiest way is that maintain allGenres
and selectedGenre
separately in state
So handleSelect
will be like
handleSelect(id) {
this.setState({
selectedGenre: id
});
}
If the i
passed to handleSelect
is the index of the genre in the genres
array then
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val, index) => {
val.isSelected = index === i;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
if the i
refers to the id
of the genre then
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val) => {
val.isSelected = val.id === i;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
I'll assume that you have some ponents being rendered, and that you want to click in these ponents... You could use bind
and pass to the callback function the index of the array... for example:
class Component extends React.Component {
constructor() {
super();
this.state = {
allGenres: [{
id: 1,
genreTitle: 'Horror',
isSelected: false
}]
}
}
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val, index) => {
val.isSelected = index === i;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
render() {
const {allGenres} = this.state;
return (
<ul>
:D
{allGenres.map((genre, i) => (
<li onClick={this.handleSelect.bind(this, i)}>
{genre.genreTitle} {genre.isSelected && 'Is Selected'}
</li>
))}
</ul>
);
}
}
I'm using bind
in the onClick callback from the li
, this way I have access to the genre index in your callback.
There are some other ways of doing this though, since you have the id of the genre, you might want to use that instead of the index, but it's up to you to decided.
How can I update isSelected
to true for the item that the user clicks on?
Here is my handleSelect
function so far:
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val, index) => {
//val.isSelected = index === true;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
This function is passed down correctly via props and is working, the issue I'm having is with the logic.
The current logic sets all items in the array to true which is incorrect. I only want to update / toggle the state of the item the user clicked.
I have an array of objects within state, here is what one of the objects looks like:
state = {
allGenres: [
{
id: 1,
genreTitle: 'Horror',
isSelected: false,
}
]
}
How can I update isSelected
to true for the item that the user clicks on?
Here is my handleSelect
function so far:
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val, index) => {
//val.isSelected = index === true;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
This function is passed down correctly via props and is working, the issue I'm having is with the logic.
The current logic sets all items in the array to true which is incorrect. I only want to update / toggle the state of the item the user clicked.
I have an array of objects within state, here is what one of the objects looks like:
state = {
allGenres: [
{
id: 1,
genreTitle: 'Horror',
isSelected: false,
}
]
}
Share
Improve this question
asked Jun 1, 2018 at 10:25
FilthFilth
3,22815 gold badges55 silver badges83 bronze badges
1
-
the
i
passed tohandleSelect
refers to what ? The index in thegenres
array or theid
of the genre, or something else ? – Gabriele Petrioli Commented Jun 1, 2018 at 10:57
4 Answers
Reset to default 2Here's how we can do it:
- On each clicked Genre, we get its
id
. - After we have the
id
, then we toggle the selected genreisSelected
flag. - Please follow
updateGenres
method, to check how we did it in an immutable way.
updateGenres(selectedId) {
const { allGenres } = this.state
this.setState({
// Here we make sure we don't mutate the state
allGenres: allGenres.map(genre => ({
...genre,
// Toggle the clicked one, and reset all others to be `false`.
isSelected: genre.id === selectedId
// If you want to keep the values of the rest genres, then the check should be:
// isSelected: (genre.id === selectedId) ? !genre.isSelected : genre.isSelected
}))
})
}
renderGenres() {
const { allGenres } = this.state
return allGenres.map(genre => <Gengre onClick={() => this.updateGenres(genre.id) })
}
render() {
return <div>{this.renderGenres()}</div>
}
The benefit of this approach is that you don't depend on the index
of the allGenres
and your toggle implementation will be decoupled to the presentation. Imagine if you change the genres sort (from ASC to DESC), then you have to change your toggle logic too.
Easiest way is that maintain allGenres
and selectedGenre
separately in state
So handleSelect
will be like
handleSelect(id) {
this.setState({
selectedGenre: id
});
}
If the i
passed to handleSelect
is the index of the genre in the genres
array then
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val, index) => {
val.isSelected = index === i;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
if the i
refers to the id
of the genre then
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val) => {
val.isSelected = val.id === i;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
I'll assume that you have some ponents being rendered, and that you want to click in these ponents... You could use bind
and pass to the callback function the index of the array... for example:
class Component extends React.Component {
constructor() {
super();
this.state = {
allGenres: [{
id: 1,
genreTitle: 'Horror',
isSelected: false
}]
}
}
handleSelect(i) {
//Get Genres
let genres = this.state.allGenres;
genres = genres.map((val, index) => {
val.isSelected = index === i;
return val;
});
//Set State
this.setState({
allGenres: genres
})
}
render() {
const {allGenres} = this.state;
return (
<ul>
:D
{allGenres.map((genre, i) => (
<li onClick={this.handleSelect.bind(this, i)}>
{genre.genreTitle} {genre.isSelected && 'Is Selected'}
</li>
))}
</ul>
);
}
}
I'm using bind
in the onClick callback from the li
, this way I have access to the genre index in your callback.
There are some other ways of doing this though, since you have the id of the genre, you might want to use that instead of the index, but it's up to you to decided.
本文标签: javascriptReact JS onClick set state of clicked indexStack Overflow
版权声明:本文标题:javascript - React JS onClick set state of clicked index - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745640859a2160737.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论