I have a component that is displayed in lists - UserListItem. When I click on it, I need to change its style to another, and change the style of the previous one to the old one. The list is stored in the array this.state.list , and the name of the style I pass through the property this.props.bodyStyle .

I can simply replace the elements with new components with new styles, however it looks bad. Can you change the style? Or can you change the properties without replacing the item?

Update

Below is the function code, which is also passed through the property:

 onClickUser(user, index){ let list = this.state.list; if(this.lastSelectedItem !== null) { for (let i = 0; i < list.length; i++) { if (list[i].key === this.lastSelected) { list[i] = <UserListItem bodyStyle="userItemBody" key={i} user={this.lastSelectedItem} index={i} onClick={this.onClickUser}/> console.log("change last selected item"); } } } list[index] = <UserListItem bodyStyle="selectedUserItemBody" key={index} user={user} index={index} onClick={this.onClickUser}/> this.lastSelected = list[index].key; this.lastSelectedItem = user; this.state = {list: list}; console.log(this.state.list === list); } 

Update number 2

Slightly changed all that. Now I have 2 components: the first is the container, the second is the display component.

Below is the container code:

 _getSortedList() { if(!this.props.items || this.props.items.length === 0) return null; let arrGroups = []; let users = this.props.items; for(let i=0;i<this.props.items.length;i++){ let group = users[i].getGroup(); if(group!==null && !arrGroups.includes(group)) arrGroups.push(group); } let listWithTitles = []; if(arrGroups.length !== 0){ arrGroups.sort(); for(let i=0;i<arrGroups.length;i++){ let list = users.filter((user)=>{ return user.getGroup() === arrGroups[i] }); list.forEach((user,index,array)=>{ listWithTitles.push(user); }); } } let usersWithoutGroup = users.filter((user)=>{ return user.getGroup() === null; }); usersWithoutGroup.forEach((user,index,array)=>{ listWithTitles.push(user); }); return listWithTitles; } render(){ return ( <ListBox source={this.state.listOfItems} selectedIndex={this.state.selIndex} onClick={this.onClick.bind(this)} title={this.props.title}/> ); } 

And here is the code for the display list:

 createListItem(item){ this.index++; let bodyStyle = "userItemBody"; if(this.index === this.props.selectedIndex){ bodyStyle = "selectedUserItemBody"; } return <UserListItem key={this.index} bodyStyle={bodyStyle} user={item} onClick={this.props.onClick} index={this.index}/>; } render() { if(!this.props.source || this.props.source.length === 0) { return null; } return( <div> <p className="ListTitle">{this.props.title}</p> <div> { this.props.source.map(this.createListItem) } </div> </div> ); } 
  • What is bad? There will be no brakes, the reactor will deal. All this canoe with virtual dom is needed for that. Show your code in short, otherwise I don’t understand what exactly you don’t like, maybe you are doing something weird. - Duck Learns to Take Cover
  • @MorePortableUp Added. - Aynur Sibagatullin
  • Why store in the state list and not the index of the last selection? - Duck Learns to Take Cover
  • one
    You overcomplicate the components, this is the problem. For a good data load for the list, one component (“smart”) should deal with, the list drawing is another component (stupid), the list element is the third component (stupid). And the data that needs to be shown to the list is for him props and not a state, they are static from the point of view of the list and the list itself does not change. - Duck Learns to Take Cover
  • one
    Well, I won’t say for operability (for example, you seem to lose context in createListItem), but you seem to be starting to pick up the idea. I would pass the isSelected flag to the UserListItem element and would define the class at the level of the element itself - Duck Learns to Hide

0