动态添加或减少子数组?

问题描述 投票:1回答:1

我是React的新手,并一直试图弄清楚如何从父组件控制组件数组。我的工作是创建一个网站,我可以在列表中添加或减去名称,但是最好的方法就是坚持下去。在这种情况下,我创建了一个react组件数组,每个组件都有标题框的受控输入,每个组件都有一个删除按钮,可以通过prop系统调用父函数的remove函数。但是,我注意到这样做时,父函数中的数组将保持正确,而子组件的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;

我想我的主要问题是处理这类问题的理想方法是什么。

javascript arrays reactjs
1个回答
1
投票

您的ID未更改的原因是您将完全形成的组件推送到阵列。

想象一下,我们有3个组件 - 格式化会有点奇怪,但希望它说明了这一点:

[ Music: { id: 0 }, Music: { id: 1 }, Music: { id: 2 } ]

当我们点击删除按钮时,用Musicid: 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}
                   ...
             />
        ); 
    }    
}

这有助于我们将对象(标题,开头,结尾等)的实际肉与它们在阵列中的位置分离,这实际上没有任何意义,只是在这里阻碍。这让我们可以在我们认为合适的情况下拼接我们的数组,并确保我们不会破坏组件与其索引之间的任何关系。

© www.soinside.com 2019 - 2024. All rights reserved.