You have a parent / child communication issue as I understand. As always, the best know approach is "props down, event up". This will ensure you easily understand how & when a variable change within a component and component behavior will not be changed by it's inner child component.
In your case, unselectedPlayerList is a prop on the child component filled by its parent component. This means parent component is owner of the data and controlling this prop value. If child component wants to modify the value of this value, it needs to ask the parent to do so, this is done by emitting an event telling the parent component what to do.
export default class ParentComponent extends LightningElement {
unselectedPlayerList = []
handleSelectPlayer (event) {
const playerName = event.detail.playerName
const playerIndex = this.unselectedPlayerList.findIndex(player => player.Name === playerName)
const shallowPlayerList = [ ...this.unselectedPlayerList ]
shallowPlayerList.splice(playerIndex, 1)
this.unselectedPlayerList = shallowPlayerList
}
}
<template>
<c-child-component
unselected-player-list={unselectedPlayerList}
onselectplayer={handlePlayerSelect}
></c-child-component>
</template>
export default class ChildComponent extends LightningElement {
@api unselectedPlayerList = []
handleSelectPlayer (event) {
this.dispatchEvent(
new CustomEvent('selectplayer', {
detail: {
playerName: event.target.title,
}
})
)
}
}
There also is another way to write the parent component if you'd like using the @track decorator.
In LWC all component attributes are reactive with a small exception around objects (array, js object). Changing an inner property of an object will not rerender the view unless decorating that object.
You can use this js for the parent component for the exact same result.
export default class ParentComponent extends LightningElement {
@track unselectedPlayerList = []
handleSelectPlayer (event) {
const playerName = event.detail.playerName
const playerIndex = this.unselectedPlayerList.findIndex(player => player.Name === playerName)
this.unselectedPlayerList.splice(playerIndex, 1)
}
}
I would not recommend using the @track version as it's heavier for performance and in any case you do stuff in a loop, every modification to the array will/might trigger view update. In first version you are assured that view will update only once which is also giving you more control on how the view (or dependent properties like getters) behave.
I hope this will help you and I invite you to read these articles: