单击时无法将不同元素的id添加到状态数组

时间:2018-04-09 08:56:17

标签: javascript reactjs

我正在尝试将svg圈子的ID设置为点击状态。

我预计ids,比方说1,2和3,将设置为状态数组:[1, 2, 3]

当我点击圈1时,阵列看起来像这样:[1]如预期的那样。当我继续点击圈2时,数组包含[2]而不是[1, 2]按预期方式。如果我继续并再次点击圈1,则数组看起来像[1, 1]。所以数组总是包含一个或多个相同的项目,但拒绝推送不同的项目,如[1, 3]

我尝试使用concat,push和spread运算符将id添加到状态数组中,所有这些都具有与上述相同的意外结果。

我在构造函数中设置了初始状态:

constructor(props) {
    super(props);
    this.state = { array: [] };
}

并尝试使用concat:

将项添加到状态数组中
test = (e) => {
    const currentArray = this.state.array;
    const newArray = currentArray.concat(e.currentTarget.__data__.id);
    this.setState({ array: newArray }, () => console.log(this.state.array));
};

和点差运算符:

test = (e) => {
    let newArray = this.state.array.splice();
    newArray.push(e.currentTarget.__data__.id);
    this.setState(prevState => ({
        array: [...prevState.array, newArray ]
    }), () => console.log(this.state.array));
};

这是圆圈元素:

<circle onClick={this.test.bind(this)}/>

我设法通过将数组设置为变量来实现此功能,并在点击时将id推入其中。但是使用React,使用state来实现这一点似乎是有意义的。我希望你能告诉我我做错了什么。

更新 - 父组件中圆圈的映射:

const nodes = this.state.nodes.map( (node) => {
    return (
        <Node
            nodeClass={this.props.nodeClass}
            data={node}
            label={node.label}
            key={node.id}
        />);
    });

1 个答案:

答案 0 :(得分:1)

您没有正确传递ID,您需要将test功能提升至Graph组件并使用constructor

创建array state

然后将数据映射到SVG中,如

<svg className="graph" width={width}  height={height} >
              {this.props.data.nodes.map( (node) =>   
                <g  onClick={this.test.bind(this, node)}>

            <Node
                data={node}
                name={node.name}
                key={node.id}
            />
                </g>)}
                <g>
                     {this.props.data.links.map( (link,i) => 
                <Link
                    key={link.target+i}
                    data={link}

                />)}
                </g>
            </svg>
  

我们在上面通过节点传递的重要事项   onClick bind

onClick={this.test.bind(this, node)}

然后调用测试函数我添加了一些额外的代码,以避免重复点击的id

test = (node) => {
  console.log(node.id, 'look here this coming from test function')
  if(this.state.array.indexOf(node.id) !== -1){
     this.setState(prevState => ({ 
        array: this.state.array.filter(d => d.id !== node.id)
    }));// this will not repeat the clicked id
  }else{
      this.setState(prevState => ({ 
        array: [...prevState.array, node.id]
    }));
  }
};

这里的完整代码

https://codepen.io/Liamm12/pen/NYeOyW?editors=0011