jquery vs react.js从列表中删除项目

时间:2016-10-03 08:29:02

标签: javascript jquery reactjs



const RenderItem = (props) => {
    return(
      <ul id="todo">
      {props.items.map((item,i) => 
        <li className='list-group-item' data-id={item.id} key={i}>{item.name}
        <button className="btn btn-sm btn-primary" onClick={() => props.remove(item.id)}>X</button>
        </li>
      )}
      </ul>
    ) 
};

const TodoItems = React.createClass({
  getInitialState() {
    return {
      items: [
        {id:1,name:"Gym"},
        {id:2,name:"Jump"},
        {id:3,name:"Racing"}
      ]
    }
  },
  remove(id){
  this.setState({
  	items: this.state.items.filter((el) => id !== el.id)
  })
  },
  render(){
    return(
      <RenderItem items={this.state.items} remove={this.remove}/>
    ) 
  }
})


ReactDOM.render(
  <TodoItems />,
  document.getElementById('container')
);
&#13;
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>

<script src="https://npmcdn.com/react@latest/dist/react-with-addons.js"></script>

<script src="https://npmcdn.com/react-dom@latest/dist/react-dom.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>
&#13;
&#13;
&#13;

我很困惑react.js中的东西如何工作,我需要presduo代码如何传递工作。我来自jquery背景,它是如此直接,只是得到正确的dom并做$(this).remove(),而在反应中我感到困惑。

<button className="btn btn-sm btn-primary" onClick={() => props.remove(item.id)}>X</button>

当你点击发生了什么?箭头功能?删除来自哪里?

2 个答案:

答案 0 :(得分:0)

React遵循单向数据绑定,这意味着数据将以单一方向流动。因此,数据存储在state中。每当state更改组件re-render时。可以在任何时间点改变状态。但是,大多数情况下它会在任何action上更改。在您的情况下,onClick()中的操作。这将调用该函数将触发id的元素的onClick()。现在,在该函数中,您将遍历state,使用setState()识别,删除和设置新状态,这将使用新数据重新呈现组件。此渲染将没有点击的元素,因为它已从状态中删除。

remove()函数从父组件传递给子组件,可以使用props访问该组件。这将是对父组件中声明的函数的引用。在单击期间,使用此引用,将调用父组件中的函数!

答案 1 :(得分:0)

在反应中,组件将根据其propsstate进行渲染。 props从父组件传递,组件可能有也可能没有内部state

使用jQuery,您可以尝试通过直接删除DOM节点来删除它。然而,在反应中,直接与DOM交互是反模式。由于当前stateprops决定了渲染的内容,因此您希望更改其中一个会导致重新渲染并显示新内容的内容。

在您的情况下,您似乎正在尝试直接修改propsprops是只读的,不应修改。由于props是从父组件传递下来的,因此您必须更改从父组件传递的内容。有几种方法可以做到这一点,例如将父组件中定义的回调函数作为可以进行此类更改的prop。但是对于此示例,使用state可能更容易/更适用。

请注意,您要更改组件的state以反映您想要查看的内容(您想要render的内容)。因此,我们假设您的组件items中有一个名为state的数组。让我们说你是

class ListDemo extends React.component {
  constructor() {
    super()

    // initialize state
    this.state = {
      items: ['thing1', 'thing2', 'thing3']
    }
  }

  onClick(index) {
    // newItems is a new array with the element at the given index removed
    // this logic doesn't handle edge cases, but that's besides the point
    const newItems = [
      ...this.state.items.slice(0, index),
      ...this.state.items.slice(index + 1)
    ]

    // here we set this component's state's items to 
    // the new state with what we want removed.
    // it will then re-render the component to reflect the new state
    this.setState({
      items: newItems
    })
  }

  render() {
    return (
      <div>
        {
          // here we render buttons for each item in the component's state's items
          // we use `onClick` to make it so that clicking the button
          // will remove it from the list
          this.state.items.map((item, index) => {
            return (
              <button 
                onClick={() => this.onClick(index)}
                key={`${item}${index}`}
              >
                {item}
              </button>
            )
          })
        }
      </div>
    )
  }
}

让我们回顾一下这个例子中发生的事情。首先,在创建组件时,它的初始state设置为包含3个元素的items数组。首次渲染时,它将为items数组中的每个元素创建一个按钮。请注意,渲染的内容完全取决于state

每个按钮还有一个回调,当它被点击时调用(由onClick设置)。此回调将从items数组中删除该特定元素,然后更新组件的state以获得新的items数组,而不包含刚删除的元素。这反过来导致重新渲染,它使用新的items数组来显示按钮。这一次,我们通过点击它删除的按钮不再存在,因为它已不在this.state.items

这是反应的关键概念之一 - 组件基于propsstate呈现,更改任何一个都会更新显示的内容。

至于为何使用箭头功能,因为它会自动bind this ListDemo组件的onClick={this.onClick.bind(this)}值。同样,您可以使用类似this的内容。这样做是必要的,因为单击按钮时import tweepy import json import jsonpickle consumer_key = "*********" consumer_secret = "*******" access_token = "************" access_token_secret = "**********" auth = tweepy.AppAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) # It make the Tweepy API call auto wait (sleep) when it hits the rate limit and continue upon expiry of the window. api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True) if (not api): print ("Can't Authenticate") sys.exit(-1) searchQuery = 'SomeHashtag' maxTweets = 10000000 # Some arbitrary large number tweetsPerQry = 100 fName = 'file.txt' sinceId = None max_id = "Latest tweet ID" tweetCount = 0 print("Downloading max {0} tweets".format(maxTweets)) with open(fName, 'a') as f: while tweetCount < maxTweets: try: if (max_id <= 0): if (not sinceId): new_tweets = api.search(q=searchQuery, lang ="en", count=tweetsPerQry) else: new_tweets = api.search(q=searchQuery, lang ="en", count=tweetsPerQry, since_id=sinceId) else: if (not sinceId): new_tweets = api.search(q=searchQuery, lang ="en", count=tweetsPerQry, max_id=str(max_id - 1)) else: new_tweets = api.search(q=searchQuery, lang ="en", count=tweetsPerQry, max_id=str(max_id - 1), since_id=sinceId) if not new_tweets: print("No more tweets found") break for tweet in new_tweets: f.write(jsonpickle.encode(tweet._json, unpicklable=False) + '\n') tweetCount += len(new_tweets) print("Downloaded {0} tweets".format(tweetCount)) max_id = new_tweets[-1].id except tweepy.TweepError as e: # Just exit if any error print("some error : " + str(e)) break print ("Downloaded {0} tweets, Saved to {1}".format(tweetCount, fName)) 的值不能保证达到您的预期。阅读this可能会更清楚。