【问题标题】:React removing an element when onClickonClick 时反应移除元素
【发布时间】:2017-12-12 19:51:27
【问题描述】:

我试图在按下 onClick 时删除一个 div。 div 存在于我拥有的父组件中

 render() {
    const listPlayers = players.map(player => (
      <Counter
        key={player.id}
        player={player}
        name={player.name}
        sortableGroupDecorator={this.sortableGroupDecorator}
        decrementCountTotal={this.decrementCountTotal}
        incrementCountTotal={this.incrementCountTotal}
        removePlayer={this.removePlayer}
        handleClick={player}
      />
    ));

    return (
      <ContainLeft style={{ alignItems: 'center' }}>
        <ProjectTitle>Score Keeper</ProjectTitle>
        <Copy>
          A sortable list of players that with adjustable scores.  Warning, don't go negative!
        </Copy>
        <div>
          <Stats totalScore={this.state.totalScore} players={players} />
          {listPlayers}
        </div>
      </ContainLeft>
    );
  }

它将props传递给删除div的按钮的子组件,这里

    return (
      <div
        style={{ display: this.state.displayInfo }}
        className="group-list"
        ref={sortableGroupDecorator}
        id="cell"
      >
        <CountCell style={{ background: this.state.color }}>
          <Row style={{ alignItems: 'center', marginLeft: '-42px' }}>
            <Col>
              <DeleteButton onClick={removePlayer}>
                <Icon name="delete" className="delete-adjust fa-minus-circle" />
              </DeleteButton>
            </Col>

(我剪掉了其余的代码,因为它很长而且在这里没有用处)

数组(一个单独的文件)被导入到父组件中,它看起来像这样

const players = [
  {
    name: 'Jabba',
    score: 10,
    id: 11
  },
  {
    name: 'Han',
    score: 10,
    id: 1
  },
  {
    name: 'Rey',
    score: 30,
    id: 10
  }
];

export default players;

所以我要做的是在主父级上编写一个函数,当在子级内部单击它时,div 被删除、删除、消失(无论最好的术语是什么)有点像“删除播放器,添加播放器”

在我的父组件上,我编写了一个函数,当在子组件中单击它时,console.log 可以工作,但是我在函数中编写的任何内容似乎都不想工作。

我正在构建的功能(正在进行中,我在这里仍然有点迷失)是:

  removePlayer() {
    console.log('this was removed');
    players.splice(2, 0, 'Luke', 'Vader');
  }

作为道具映射到这里

const listPlayers = players.map(player => (
  <Counter
    key={player.id}
    player={player}
    name={player.name}
    sortableGroupDecorator={this.sortableGroupDecorator}
    decrementCountTotal={this.decrementCountTotal}
    incrementCountTotal={this.incrementCountTotal}
    removePlayer={this.removePlayer}
    handleClick={player}
  />
));

并在这里传递给孩子:

render() {
const {
  name,
  sortableGroupDecorator,
  decrementCountTotal,
  incrementCountTotal,
  removePlayer
} = this.props;

return (
  <div
    style={{ display: this.state.displayInfo }}
    className="group-list"
    ref={sortableGroupDecorator}
    id="cell"
  >
    <CountCell style={{ background: this.state.color }}>
      <Row style={{ alignItems: 'center', marginLeft: '-42px' }}>
        <Col>
          <DeleteButton onClick={removePlayer}>
            <Icon name="delete" className="delete-adjust fa-minus-circle" />
          </DeleteButton>

我知道这一切都很冗长,我想提供尽可能多的细节,因为 React 对我来说仍然是新事物,而且我对一些措辞感到困惑。感谢您提前提供帮助

【问题讨论】:

  • 您可能需要考虑将播放器置于状态,因为如果您只是更改范围外的变量,组件将不会重新渲染。
  • 这样的父组件我会放this.state = {players: players};?
  • 差不多,是的。不要把它放在渲染函数中!使用像 componentWillMount 这样的生命周期函数或将其放入构造函数中。然后在您的渲染函数中始终引用this.state.players。然后在您的 removePlayer() 函数中,从状态中复制数组,对其进行变异(拼接您的播放器或其他),然后使用变异副本调用 this.setState()。
  • 好的,我了解这里的大致内容,有些事情我并不完全精通,但这是我第一次了解如何做到这一点(我一直在努力数周)。
  • 太棒了。祝你好运。如果你需要帮助的话。

标签: javascript reactjs ecmascript-6


【解决方案1】:

我们在聊天中整理出来。不出所料,这是国家的问题。

我做了一个小半伪sn-p,用cmets作为解释:

import React, { Component } from 'react';

// Your player constant, outside the scope of any React component
// This pretty much just lives in your browser as a plain object.
const players = [
  {
    name: 'Jabba',
    score: 10,
    id: 11
  },
  {
    name: 'Han',
    score: 10,
    id: 1
  },
  {
    name: 'Rey',
    score: 30,
    id: 10
  }
];

class App extends Component {

  constructor() {
    super();

    this.state = {
      players, // ES6 Syntax, same as players: players
      // Add all your other stuff here
    };
  }

  removePlayer(id) {
    const newState = this.state;
    const index = newState.players.findIndex(a => a.id === id);

    if (index === -1) return;
    newState.players.splice(index, 1);

    this.setState(newState); // This will update the state and trigger a rerender of the components
  }

  render() {

   const listPlayers = this.state.players.map(player => { // Note the this.state, this is important for React to see changes in the data and thus rerender the Component
      <Counter
        ..

        removePlayer={this.removePlayer.bind(this)} //bind this to stay in the context of the parent component
      />
    });

    return (
      <div>
        {listPlayers}
      </div>
    );
  }
}





//////////////////////////////////////// Child component

....

<DeleteButton onClick={() => this.props.removePlayer(this.props.player.id)}>

....

【讨论】:

  • 当点击删除功能时,它会从最后一个元素中删除。我无法删除适当的元素。
  • @EDISONJ 你也可以使用过滤器。
【解决方案2】:

这是我解决这个问题的方法

我已经为元素添加了一个 id 然后用函数 remove 我把它销毁了

const closenotif = () => document.getElementById("notif").remove()
 
<div id="notif">
       <button onClick={destroy}> close </button>
</div> 

NB : 元素在当前文档中被销毁 所以在当前渲染中

在 Next JS 上完美运行

如果您使用带有 react 的实时渲染,这可能不起作用

我会建议你在这种情况下与州合作

【讨论】:

    【解决方案3】:

    对整个应用程序的工作原理有点困惑,但我会尽力帮助你。

    要对 dom 做出响应更改,您必须将 players 放入 state。因此,在removePlayer 中,您在局部变量中复制this.state.players(只是为了不直接在state 中更改数组,这是一个好习惯),然后在此局部变量中进​​行拆分,最后您setState({ players: localPlayers}).

    这样“div”将被删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-30
      相关资源
      最近更新 更多