React - 创建一个删除按钮,删除它的DOM父级和相应的状态项

时间:2017-11-06 11:04:13

标签: javascript reactjs

我有一个基本的待办事项列表,我不知道如何为每个待办事项添加删除按钮。在传统的DOM编程中,我只是向按钮添加一个事件监听器,并删除父和各自的数组索引数据。有了React,我不太确定如何构建它。

我的问题是:

  1. 让它正常运作
  2. 知道如何(以及如果)我应该为此功能创建一个新组件。

    var TodoItems = React.createClass({
    
      render: function() {
          var attr = this.props
          var todoEntries = attr.entries;
    
    
    
          var listItems = todoEntries.map((item) => {
              return <li key={item.key}>{item.text} <input type="button" value="DELETE"></input></li>
          });
    
          return (
              <ul className="theList">
                {listItems}
            </ul>
          );
      }
    
    });
    
    
    var TodoList = React.createClass({
        getInitialState: function() {
            return {
                items: []
            };
        },
    
      addItem: function(e) {
          var itemArray = this.state.items;
    
          itemArray.push({
              text: this._inputElement.value,
              key: Date.now()
          });
    
          this.setState({
              items: itemArray
          });
    
          this._inputElement.value = "";
    
          e.preventDefault();
      },
    
      render: function() {
    
          return (
              <div className="todoListMain">
              <div className="header">
                <form onSubmit={this.addItem}>
                  <input ref={(a) => this._inputElement = a}
                   placeholder="enter task">
                  </input>
                  <button type="submit">add</button>
                </form>
              </div>
    
              <TodoItems entries={this.state.items}/>
    
            </div>
          );
      }
    });
    
    
    
    
    var destination = document.querySelector("#container");
    
    ReactDOM.render(
      <div>
        <TodoList/>
      </div>,
      destination
    

    );

2 个答案:

答案 0 :(得分:1)

先决条件理解

我相信开始回答你的问题,你需要对React背后的核心概念有一个充分的理解。

  

您的观点代表您的数据

您的React组件描述如何向用户呈现数据。 因此,如果您希望更改视图中的内容,则应更改数据。

在几乎所有情况下,您都不需要考虑DOM操作。 React将根据对数据的更改来更改您的视图。

  

在传统的DOM编程中,我只是向按钮添加一个事件监听器,并删除父和各自的数组索引数据。

进一步阅读

解决方案

&#13;
&#13;
const { Component } = React;
const { render } = ReactDOM;

const defaultList = [
  'Item 1',
  'Item 2',
  'Item 3',
];

const List = (props) => (
  <ul>
    {props.items.map((item, index) => (
      <li key={index}>
        {item}
        <br />
        <button onClick={() => props.removeItem(index)}>Remove</button>
      </li>
    ))}
  </ul>
);

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      items: defaultList,
    };
  }
  
  removeItem(removeIndex) {
    this.setState((state) => ({
      ...state,
      items: this.state.items.filter((item, index) => index !== removeIndex)
    }))
  }
  
  reset() {
    this.setState((state) => ({
      ...state,
      items: defaultList,
    }))
  }
  
  render() {
    return (
      <div>
        <List
          items={this.state.items}
          removeItem={this.removeItem.bind(this)}
        />
        <button onClick={this.reset.bind(this)}>Reset</button>
      </div>
    );
  }
}
                   
render(<App />, document.getElementById('root'));
&#13;
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
</head>
<body>
  <div id="root"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
</body>
</html>
&#13;
&#13;
&#13;

现在我们已经有了先决条件的理解,我们可以通过解决方案。

您的数据是存储在某处的项目列表(可能是组件状态或Redux存储)。我们将在示例中使用组件状态来简化操作:

const defaultList = [
  'Item 1',
  'Item 2',
  'Item 3',
];

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      items: defaultList,
    };
  }
  ...
}

我们知道视图是状态的表示,要删除视图中的项目,我们必须从当前状态中删除该项目。为了实现这一点,我们可以定义一个函数,该函数将接受一个描述要删除的项的参数(在我们的例子中,它是一个索引,但它可以是一个项目对象id,具体取决于您的列表的建模方式)。删除它是一种过滤掉具有与提供的参数匹配的索引的项目的情况。创建并设置新的状态对象。

class App extends Component {
  ...
  removeItem(removeIndex) {
    this.setState((state) => ({
      ...state,
      items: this.state.items.filter((item, index) => index !== removeIndex)
    }))
  }
  ...
}

此函数通过其List传递给props组件,并在每个按钮的onClick处理程序中调用。

const List = (props) => (
  <ul>
    {props.items.map((item, index) => (
      <li key={index}>
        {item}
        <br />
        <button onClick={() => props.removeItem(index)}>Remove</button>
      </li>
    ))}
  </ul>
);

答案 1 :(得分:0)

我认为最简单的方法是为TODO创建一个处理其已删除状态的组件:

{{1}}