Javascript 状态数组中的更改不会通过道具更改子级
最近,我一直在使用输入文本框的动态控件,每个文本框都有自己的id。但是,我注意到,如果我存储了一个元素数组,并且每个元素都是一个具有不同变量的对象,那么对象中这些变量的任何更改都不会对更新子组件(通过道具接收状态)作出警报反应。我试图根据文档控制输入,但我不明白为什么正常非数组和非对象变量的父级状态的更改会被子级识别为props的更改,而不是正常状态数组的更改。这是我的家长代码:Javascript 状态数组中的更改不会通过道具更改子级,javascript,Javascript,最近,我一直在使用输入文本框的动态控件,每个文本框都有自己的id。但是,我注意到,如果我存储了一个元素数组,并且每个元素都是一个具有不同变量的对象,那么对象中这些变量的任何更改都不会对更新子组件(通过道具接收状态)作出警报反应。我试图根据文档控制输入,但我不明白为什么正常非数组和非对象变量的父级状态的更改会被子级识别为props的更改,而不是正常状态数组的更改。这是我的家长代码: import React, {Component} from 'react'; import Music from
import React, {Component} from 'react';
import Music from './music'
import axios from 'axios';
import update from 'immutability-helper';
class Selection {
constructor(){
this.music = '';
this.beginning = '';
this.the_end = '';
}
setTitle=(title)=>{
this.music = title;
}
setStart=(start)=>{
this.beginning = start;
}
setEnd=(end)=>{
this.the_end = end;
}
}
class Practice extends React.Component{
constructor(props){
super(props);
this.state = {
selections: Array(0),
test: 0,
}
this.removeSong = this.removeSong.bind(this);
}
removeSong(index){
var newArray = this.state.selections.slice();
newArray.splice(index, 1);
this.setState({selections: newArray, test: this.state.test+=1});
}
addAnotherSong=()=>{
var newArray = this.state.selections.slice();
newArray.push(new Selection());
this.setState({ selections: newArray, test: this.state.test+=1});
}
render(){
return(
<div>
<button onClick={() => this.props.practice()}>Log Practice Session</button>
<h1>{this.props.time}</h1>
<form >
Description: <input type="form" placeholder="How did it go?" name="fname"/><br/>
</form>
<button onClick={()=>this.addAnotherSong()}>Add Another Piece</button>
<button onClick={()=>this.setState({test: this.state.test})}>Will it now Update?</button>
{
this.state.selections.map((child, index) => (
this.state.selections[index].music,
<Music key={index} number={index} subtract={this.removeSong}
Title={this.state.test} Start={this.state.selections[index].beginning}
End={this.state.selections[index].the_end} changeTitle={this.state.selections[index].setTitle}
changeStart={this.state.selections[index].setStart} changeEnd={this.state.selections[index].setEnd}
/>
))
}
</div>
);
}
}
export default Practice;
import React,{Component}来自'React';
从“./音乐”导入音乐
从“axios”导入axios;
从“不变性助手”导入更新;
选课{
构造函数(){
这个。音乐=“”;
这个。开始=“”;
this.the_end='';
}
setTitle=(标题)=>{
这个。音乐=标题;
}
设置开始=(开始)=>{
这个。开始=开始;
}
setEnd=(end)=>{
this.the_end=end;
}
}
课堂实践扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
选择:数组(0),
测试:0,
}
this.removeSong=this.removeSong.bind(this);
}
removeSong(索引){
var newArray=this.state.selections.slice();
新阵列拼接(索引,1);
this.setState({selections:newArray,test:this.state.test+=1});
}
添加其他歌曲=()=>{
var newArray=this.state.selections.slice();
newArray.push(新选择());
this.setState({selections:newArray,test:this.state.test+=1});
}
render(){
返回(
this.props.practice()}>记录练习会话
{this.props.time}
说明:
this.addAnotherSong()}>添加另一首歌曲
this.setState({test:this.state.test}}>现在会更新吗?
{
this.state.selections.map((子级,索引)=>(
this.state.selections[index].music,
))
}
);
}
}
出口违约行为;
如您所见,我有一个状态为的数组,其中包含从Selection类构造的对象。以下是除非在非数组类型“this.state.test”中发生更改,否则不会更新的子级
import React,{Component}来自'React';
从“./input”导入InputBox;
类音乐扩展了React.Component{
建造师(道具){
超级(道具);
}
shouldComponentUpdate(新道具){
如果(this.props!==newProps){
返回true;
}否则{
console.log(“wassup”);
返回false;
}
}
render(){
返回(
{this.props.number}
this.props.subtract(this.props.number)}>删除{this.props.number}
{this.props.Title}
)
}
}
导出默认音乐;
最后,这是那个孩子的孩子们
import React,{Component} from 'react';
class InputBox extends React.Component{
constructor(props){
super(props);
this.state = { value: '' }
this.handleChange = this.handleChange.bind(this);
}
handleChange(event){
this.setState({value: event.target.value});
this.props.updateInput(this.state.value, this.props.identity);
console.log("test" + this.props.cValue);
}
shouldComponentUpdate(newProps){
if(this.props !== newProps){
console.log("Updating Input Component");
return true;
} else {
console.log("yo");
return false;
}
}
render(){
return(
<input type="text"onChange={this.handleChange} value={this.props.cValue}/>
)
}
}
export default InputBox;
import React,{Component}来自'React';
类InputBox扩展了React.Component{
建造师(道具){
超级(道具);
this.state={value:''}
this.handleChange=this.handleChange.bind(this);
}
手变(活动){
this.setState({value:event.target.value});
this.props.updateInput(this.state.value,this.props.identity);
console.log(“test”+this.props.cValue);
}
shouldComponentUpdate(新道具){
如果(this.props!==newProps){
日志(“更新输入组件”);
返回true;
}否则{
控制台日志(“yo”);
返回false;
}
}
render(){
返回(
)
}
}
导出默认输入框;
如果这个问题不好,请告诉我。但是,任何帮助都是值得感激的。谢谢您将您的状态视为一个可变对象-React中的状态永远不应该发生突变,状态更改应该始终是一个全新的对象 例如,我们只有一个
选择
处于状态。选择
:
[ { music: 'music', beginning: 'beginning', the_end: 'ending' } ]
如果Music
组件最终调用了setStart('newBeginning')
,那么在我们的状态下,我们将得到以下结果:
[ { music: 'music', beginning: 'newBeginning', the_end: 'ending' } ]
这看起来一切都进行得很顺利,但是React在默认情况下实际上不会接受此更改,因为state.selections
仍然引用相同的数组
要解决此问题,您必须了解如何在修改单个项时更新数组引用。您已经在当前状态下通过调用slice
在removeSong
和addAnotherSong
中完成了此操作<代码>切片返回一个新数组,因此没有问题
我建议在实践
中使用方法修改单个选择
s,而不是每个选择
修改自己
类似这样的方法可能会奏效:
class Practice extends React.Component{
updateSelectionBeginning(index, newBeginning){
var newArray = this.state.selections.slice();
newArray[index].beginning = newBeginning;
this.setState({selections: newArray});
}
}
然后我们会通过道具把它传给我们的孩子,他们会调用
updateselectionstart(FOO,BAR)
。这让我们可以更新状态,同时保持状态不变。它可以工作!所以,如果我理解正确的话,一个不可变的状态数组只有当它被设置为自身的一个更改副本时才能被更改。我想我现在明白了。非常感谢
class Practice extends React.Component{
updateSelectionBeginning(index, newBeginning){
var newArray = this.state.selections.slice();
newArray[index].beginning = newBeginning;
this.setState({selections: newArray});
}
}