Javascript ReactJS——父状态更新时,子道具不更新/重新提交
简而言之: 我正在制作一个网页来简化我有时和中学生玩的游戏。我使用一个有状态的React组件向孩子传递道具。问题是当父对象的状态更新时,子对象的道具不会更新/重新渲染。我在这里看了几个问题/答案,但没有一个与我的问题完全匹配。我还制作了其他几个具有相同设置的网页,从来没有遇到过这个问题。我甚至回去将这段代码与我其他一些“成功”的项目进行了比较,但我不知道这段代码有什么不同之处/使它无法工作 更具体地说:我正在制作一个记分板,其中列出了每个团队的得分线、他们的得分以及团队可以采取的行动的按钮菜单。其中一个动作是“增加10码”。目前,父组件“记分牌”的功能“增加10码”上有一个按钮。它会给球队的码数增加10,最终会将他们的足球化身移动10码。我注意到,在某一点上,虽然它正确地更新了父记分板的状态,但在渲染中码的状态并没有改变。button/gain10功能还可以更改团队状态的“turn”部分,该部分应禁用按钮,但不会。在我看来,父级正在传递构造函数中设置的初始道具,并且在Javascript ReactJS——父状态更新时,子道具不更新/重新提交,javascript,reactjs,rendering,state,Javascript,Reactjs,Rendering,State,简而言之: 我正在制作一个网页来简化我有时和中学生玩的游戏。我使用一个有状态的React组件向孩子传递道具。问题是当父对象的状态更新时,子对象的道具不会更新/重新渲染。我在这里看了几个问题/答案,但没有一个与我的问题完全匹配。我还制作了其他几个具有相同设置的网页,从来没有遇到过这个问题。我甚至回去将这段代码与我其他一些“成功”的项目进行了比较,但我不知道这段代码有什么不同之处/使它无法工作 更具体地说:我正在制作一个记分板,其中列出了每个团队的得分线、他们的得分以及团队可以采取的行动的按钮菜单。
gain10()
中调用setState()
以更新道具后,不会重新渲染。不过,它们正在更新
代码是公认的混乱,因为a)我只是一个谦逊的数学老师,非正式地学会了自己编写代码,b)这是我最初尝试做的(从状态传递整个团队对象,然后在创建子组件时将其分离)与渲染时直接从状态传递信息的混合。我可以继续讲述你在这段代码中看到的奇妙之处,但让我们开始吧:
class Scoreboard extends React.Component {
constructor(props) {
super(props)
this.state = {
team1: {
num: 1,
yards: 10,
score: 0,
hasBall: true,
turn: true,
css: "top",
ball: 'https://i.ibb.co/6n6bt0Y/football1.png',
class: 'v-fb',
style: {top: 2 + "em", left: 26.5 + "em"}
},
team2: {
num: 2,
yards: 20,
score: 10,
hasBall: true,
turn: false,
css: "top",
ball: 'https://i.ibb.co/ngfTbLW/football2.png',
class: 'v-fb',
style: {top: 42.5 +"em", left: 21.5 + "em"}
},
team3: {
num: 3,
yards: 10,
score: 0,
hasBall: true,
turn: false,
css: "left",
ball: 'https://i.ibb.co/vvWSCYW/football3.png',
class: 'h-fb',
style: {top: 42.5 +"em", left: 21.5 + "em"}
},
team4: {
num: 4,
yards: 10,
score: 0,
hasBall: true,
turn: false,
css: "left",
ball: 'https://i.ibb.co/vDXmqb5/football4.png',
class: 'h-fb',
style: {top: 42.5 +"em", left: 21.5 + "em"}
}
}
this.gain10 = this.gain10.bind(this)
}
gain10(e) {
var id = e.target.id
console.log(this.state.team1)
this.setState((state) => {
state[id].yards += 10
state[id].turn = !state[id].turn
})
}
render() {
return(
<div id="scoerboard">
<TeamBoard team="team1"
yards = {this.state.team1.yards}
score = {this.state.team1.score}
turn = {this.state.team1.turn}
teamData = {this.state.team1}
func={this.gain10}/>
</div>
)
}
}
const TeamBoard = (props) => {
var id = `${props.team}-board`
return (
<div id={id}>
<img src={props.teamData.ball} class={props.teamData.class} style={props.teamData.style}/>
<p>team {props.teamData.num} stats</p>
<p>
<span class="board-label">Yards:</span> {props.yards}
<span class="board-label">Score:</span> {props.score}
</p>
<button id={props.team} onClick={props.func} disabled={!props.turn}>go</button>
</div>
)
}
类记分板扩展React.Component{
建造师(道具){
超级(道具)
此.state={
第1组:{
数目:1,,
码数:10,
分数:0,
哈斯波尔:是的,
转身:对,
css:“顶部”,
球:'https://i.ibb.co/6n6bt0Y/football1.png',
类别:“v-fb”,
样式:{top:2+“em”,left:26.5+“em”}
},
第2组:{
数字:2,
码数:20,
得分:10分,
哈斯波尔:是的,
转向:错误,
css:“顶部”,
球:'https://i.ibb.co/ngfTbLW/football2.png',
类别:“v-fb”,
样式:{top:42.5+“em”,left:21.5+“em”}
},
第三小组:{
数字:3,
码数:10,
分数:0,
哈斯波尔:是的,
转向:错误,
css:“左”,
球:'https://i.ibb.co/vvWSCYW/football3.png',
类别:“h-fb”,
样式:{top:42.5+“em”,left:21.5+“em”}
},
第4组:{
数字:4,
码数:10,
分数:0,
哈斯波尔:是的,
转向:错误,
css:“左”,
球:'https://i.ibb.co/vDXmqb5/football4.png',
类别:“h-fb”,
样式:{top:42.5+“em”,left:21.5+“em”}
}
}
this.gain10=this.gain10.bind(this)
}
收益10(e){
var id=e.target.id
console.log(this.state.team1)
this.setState((状态)=>{
状态[id]。码数+=10
状态[id]。回合=!状态[id]。回合
})
}
render(){
返回(
)
}
}
const TeamBoard=(道具)=>{
var id=`${props.team}-board`
返回(
团队{props.teamData.num}stats
码:{props.Yards}
分数:{props.Score}
去
)
}
整个代码(哦,亲爱的)和视觉效果都可以在屏幕上看到,尽管正在积极地进行更改以继续尝试解决这个问题…调用setState有两个问题。第一个(也是最简单的)是函数不返回任何内容。第二个更微妙的问题是,状态变化只被跟踪了一个层次。更改
team1.yards
的值时,team1对象未更改,因此不会触发重新渲染。您应该返回一个带有更新值的新对象。类似于return{[id]:{…state[id],yards:state[id]。yards+10,turn:!state[id]。turn}}
应该可以解决这两个问题。非常感谢,它确实解决了这两个问题!如果您愿意详细说明的话,我对您的代码有一个(或两个或三个)问题。在状态[id]之前,“…”做什么?这是否类似于定义状态中的哪个键正在更改,然后是特定对象中的哪些键正在更改?这样可以避免覆盖整个“团队”对象并丢失未更新的键/值?您应该阅读以下内容:。前提是您正在创建一个新对象,该对象是旧对象的副本(即,包含相同的键/值对),然后更新yards
和turn
属性的新值。调用setState有两个问题。第一个(也是最简单的)是函数不返回任何内容。第二个更微妙的问题是,状态变化只被跟踪了一个层次。更改team1.yards
的值时,team1对象未更改,因此不会触发重新渲染。您应该返回一个带有更新值的新对象。类似于return{[id]:{…state[id],yards:state[id]。yards+10,turn:!state[id]。turn}}
应该可以解决这两个问题。非常感谢,它确实解决了这两个问题!如果您愿意详细说明的话,我对您的代码有一个(或两个或三个)问题。在状态[id]之前,“…”做什么?这是否类似于定义状态中的哪个键正在更改,然后是特定对象中的哪些键正在更改?这样可以避免覆盖整个“团队”对象并丢失未更新的键/值