Reputation: 490
I have been working with the React framework for a couple weeks now, but I am surprised by new things very often. I am working on the login/game lobby/ server lobby of a game I am making for a group project.
I am a bit confused about state currently. So far to change my state I have been using:
setState({stateProperty: newValue});
The reason I am confused is that I have an array in state that contains a list of elements. Each element is a line displayed on the screen, and I need to change one of words in this element. The element needs to be seen by all viewers of the site, so these lines must be kept in state.
The problem is that this word is a property of this element. To be able to set the state I need to pass a new version of this element, but I cannot do this because I would need to make a version of this element with a different property... I cannot change properties.
It seems I have to change the state of the state or something? How would I go about doing this?
The properties of the array get pushed in such a way, where I am trying to change "status" of the "GameLine" object, and "GameLine" is one of the elements in the array "children":
children.push(
<GameLine
players={allPlayers}
lobbyStateChange={this.lobbyStateChange.bind(this)}
joinState={this.joinState.bind(this)}
joinAppears={this.joinAppears.bind(this)}
handleLobbyChange={this.handleLobbyChange.bind(this)}
lobby={newLobbyName}
owner={owner}
type={newGameType}
difficulty={newDifficulty}
status={newStatus}
number={gamesAmount}
key={"gameLineKey"+owner}
className="gamesGames"
/>
);
Sorry if this is a bad question! Thanks for the help in advance!
Upvotes: 0
Views: 103
Reputation: 490
Severiaan's answer is exactly what I was looking for! Thanks so much!
To reiterate what my question was, for future readers:
Here is the initial state of my program:
this.state = {
inLogin: true,
inGameLobby: false,
inLobbyCreate: false,
currentGame: 0,
message: "",
allMessages: [],
messageAmount: 0,
games: 0,
allGameLines: [],
allGames: [],
lobbyName: "",
owner: "",
gameType: "",
difficulty: "",
status: "",
user: "",
allUsers: [],
userAmount: 0,
selectedGame: "",
buttonVisibility: "hidden",
username: "",
role: "",
currentTab: "logTab",
allLobbies: [],
allLobbyPlayers: [],
playersReady: [],
allGameLobbyMessages: [],
}
On my webpage, every time someone creates a 'game lobby', a 'gameLine' is created that other players can click so to be able to join the lobby. The 'gameLine' displays the amount of players in the lobby as 'status'. I was uncertain how to change this property of the 'gameLine'.
The state property 'allGameLines' is a list of the 'gameLine' element, where the element (is complicated and is unnecessary to display all the code for, not needed to understand the question) is going to be re-rendered when someone joins or leaves the lobby.
The issue was that the 'gameLine' element has its own properties. Normally when editing state, you would use the command:
setState({
allGameLines: newAllGameLines,
});
'setState' cannot be used in this case because we cannot create a new version 'newAllGameLines' because to create a new version we would need to change the property 'status'.
"Lukasz 'seVeriaan' Grela" has the perfect solution of going into 'allGameLines' and changing 'status' directly. The solution would look something like:
lobbyStateChange(newGameStatus, allLobbyPlayers, jTerm){
this.setState(prevState =>({
inGameLobby: true,
buttonVisibility: "hidden",
allLobbyPlayers,
allGameLines: {
...prevState.allGameLines,
jTerm: {
props: {
status: newGameStatus,
}
}
},
}));
}
Thank you all for the help!
Upvotes: 1
Reputation: 6258
You can change state granularly you have to copy unmodified state, eg
this.state ={ prop1:”abc”,
prop2:{
Sub1:”abc1”,
Sub2:”def2”
}:
this.setState(prevState=>({
prop2:{
...prevState.prop2,
Sub2:”changed”
}
});
This will change sub2 only.
Upvotes: 0