我是React的新手,并一直试图弄清楚如何从父组件控制组件数组。我的工作是创建一个网站,我可以在列表中添加或减去名称,但是最好的方法就是坚持下去。在这种情况下,我创建了一个反应组件数组,每个组件都有标题框的受控输入,每个组件都有一个删除按钮,可以通过prop系统调用父函数的删除功能。但是,我注意到,这样做时,父函数中的数组将保持正确,而子组件的id不会更改为重新排序,从而破坏后续删除。我确信我做错了,并希望找到一种更好,更有效的方法。谢谢!
import React, {Component} from 'react';
import Music from './music'
import axios from 'axios';
var childrenComponents = [];
class Selection {
constructor(){
this.music = '';
this.beginning = 0;
this.the_end = 0;
}
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 = {
number_music: 0,
number: 0,
selections: Array(0).fill(null),
deletions: 0,
}
this.addAnotherSong = this.addAnotherSong.bind(this);
this.removeSong = this.removeSong.bind(this);
this.renderMusicPlayed = this.renderMusicPlayed.bind(this);
}
removeSong(index){
if((this.state.number_music-1) >= 0){
alert(index);
for(var i = 0; i < (this.state.selections.length-1); i++){
console.log(this.state.selections[i].music);
}
childrenComponents.splice(index, 1);
this.setState({selections: this.state.selections.filter((_, i) => i !== index),
number_music: this.state.number_music - 1,
deletions: this.state.deletions += 1});
console.log("========================");
for(var i = 0; i < (this.state.selections.length-1); i++){
console.log(this.state.selections[i].music);
}
console.log("///////////////////////////////////////////////////");
}
}
addAnotherSong(){
this.state.selections.push(new Selection());
var i = this.state.number_music;
childrenComponents.push(
<Music key={i} number={i} subtract={this.removeSong}
Title={this.state.selections[i].music} Start={this.state.selections[i].beginning}
End={this.state.selections[i].the_end} changeTitle={this.state.selections[i].setTitle}
changeStart={this.state.selections[i].changeStart} changeEnd={this.state.selections[i].changeEnd}/>
);
this.setState({ number_music: this.state.number_music += 1, number: this.state.number += 1});
}
renderMusicPlayed(){
return (
<div>
{childrenComponents}
</div>
);
}
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>
{this.renderMusicPlayed()}
<button onClick={()=>this.addAnotherSong()}>Add Another Piece</button>
{this.state.number_music}
</div>
);
}
}
export default Practice;
那是父母。 这是孩子:
import React, {Component} from 'react';
import InputBox from './input';
class Music extends React.Component{
constructor(props){
super(props);
this.state = {
title: null,
start: null,
end: null
}
}
componentWillReceiveProps(props){
this.setState({ title: this.props.Title});
}
render(){
return(
<div>
<InputBox initialValue={this.props.number} cValue={this.props.Title} identity={this.props.number} updateInput={this.props.changeTitle} />
<InputBox initialValue="Starting Measure" cValue={this.props.Start} identity={this.props.number} updateInput={this.props.changeStart} />
<InputBox initialValue="Ending Measure" cValue={this.props.End} identity={this.props.number} updateInput={this.props.changeEnd} />
<button onClick={()=> this.props.subtract(this.props.number)}>Delete</button>
</div>
)
}
}
export default Music;
这就是大孩子可以这么说:
import React,{Component} from 'react';
class InputBox extends React.Component{
constructor(props){
super(props);
this.state = { value: this.props.initialValue, text: "" }
this.handleChange = this.handleChange.bind(this);
}
handleChange(event){
this.setState({value: event.target.value});
this.props.updateInput(this.state.value, this.props.identity);
}
render(){
return(
<input type="text" onChange={this.handleChange} value={this.state.cValue}></input>
)
}
}
export default InputBox;
我想我的主要问题是处理这类问题的理想方法是什么。
答案 0 :(得分:1)
您的ID未更改的原因是您将完全形成的组件推送到阵列。
想象一下,我们有3个组件 - 格式化会有点奇怪,但希望它说明了这一点:
[ Music: { id: 0 }, Music: { id: 1 }, Music: { id: 2 } ]
当我们点击删除按钮时,请Music
与id: 1
说明,我们最终会这样:
[ Music: { id: 0 }, Music: { id: 2 } ]
我们将右Music
拼接出来,但我们现在有一个错误的索引 - 我们从未真正用Music
更改id: 2
。在Music
函数中动态构建render
组件会更容易(在我看来)。
实际上,您的childrenComponents
数组并非全部有用 - 在其中创建的Music
组件都是在记录 i 时创建的:
Title={this.state.selections[i].music}
Start={this.state.selections[i].beginning}
End={this.state.selections[i].the_end}
依此类推。
我们可以很容易地简化这一过程,并将所有这些合并到一个数组中。
想象一下,我们有一个数组字段state.children
,看起来像这样:
[
{ title: _____, start: _____, end: ____, ... },
{ title: _____, start: _____, end: ____, ... },
{ title: _____, start: _____, end: ____, ... },
]
这在很大程度上要清晰得多:我们的数据整合在一个单一的地方,我们并没有通过一些任意索引将它们捆绑在一起。您已使用selections
数组在某种意义上完成了此操作,但由于您还在使用childrenComponents
,因此您需要对基本相同的数据进行双重管理。
我们也很容易使用以下内容来呈现它:
render() {
{
this.state.children.map((child, index) => (
<Music key={index}
number={index}
subtract={this.removeSong}
Title={this.state.children[index].title}
...
/>
);
}
}
这有助于我们将对象(标题,开头,结尾等)的实际肉与它们在阵列中的位置分离,这并不是真正意义上的任何东西,只是在这里阻碍。这让我们能够在我们认为合适的情况下拼接我们的阵列,并确保我们不会破坏我们的组件与其索引之间的任何关系。