使用React更新状态

时间:2015-11-19 23:16:33

标签: ajax mongodb reactjs

我正在使用React,MongoDB,Express和Node创建博客。我有三个组件:App,List和Item。该项目是博客文章;该列表是博客帖子列表,该应用程序包含一个输入文本并提交的位置。我最终会添加更多功能,但我想确定我是否遵守React的最佳实践(我怀疑我是)。

所以在App中,我的getInitialState包含一系列帖子(帖子)和一串输入文本(postbody)。我使用componentDidMount向我的数据库发出AJAX GET请求,因此用户可以看到所有帖子。

为了处理输入文本我刚刚创建了一个简单的handleChange函数来更新postbody的状态。

我还有一个handleClick函数,它抓取this.state.postbody然后POST它数据库。但是,相同的函数也会使数据库的单独GET请求更新posts数组的状态。这看起来不对!难道不能以其他方式处理并自动更新吗? *这是我的主要问题。 *

另外,如果我需要进一步破坏组件,或者我违反了使用React的最佳做法(例如,在错误的地方更改状态,或者错误地使用道具),请告诉我。

var React = require('react');

var Item = React.createClass({
  render: function() {
    return (
      <div>
        <h2>{this.props.postbody}</h2>
      </div>
    )
  }
})

var List = React.createClass({

  render: function() {
    return (
      <div>
        {this.props.array.map(function(post) {

          return (
            <Item postbody={post.postbody}></Item>
          )
        })}
      </div>
    )
  }
})

var App = React.createClass({

  getInitialState: function() {
    return {
       posts: [],
       postbody: ''
    }
  },

  componentDidMount: function() {
    $.ajax({
      type: 'GET',
      url: '/api/blogPosts',
      success: function(data) {
        this.setState({posts: data});
      }.bind(this)
    })
  },

  handleClick: function() {

    event.preventDefault();

    var blogPost = this.state.postbody;

    $.ajax({

      type: 'POST',
      url: '/api/blogPosts',
      data: { postbody: blogPost }
    });

    $.ajax({
      type: 'GET',
      url: '/api/blogPosts',
      success: function(data) {
        this.setState({posts: data});
      }.bind(this)
    })
  },

  handleChange: function(event) {

    this.setState({ postbody: event.target.value})
  },

  render: function() {
    return (
      <div>
        <form action="/api/blogPosts" method="post">
            <input onChange={this.handleChange} type="text" name="postbody"></input>
            <button type="button" onClick={this.handleClick}>Submit</button>
        </form>
        <List array={this.state.posts} />
      </div>
    )
  }
})

1 个答案:

答案 0 :(得分:2)

好吧,实际上因为你只有一个Add api调用,所以你可以这样做。您只需将blogPost推送到帖子请求中的帖子数组即可。此外,您可能希望使用表单onSubmit。

var React = require('react');

var Item = React.createClass({
  render: function() {
    return (
      <div>
        <h2>{this.props.postbody}</h2>
      </div>
    )
  }
})

var List = React.createClass({

  render: function() {
    return (
      <div>
        {this.props.array.map(function(post) {

          return (
            <Item postbody={post.postbody}></Item>
          )
        })}
      </div>
    )
  }
})

var App = React.createClass({

  getInitialState: function() {
    return {
       posts: [],
       postbody: ''
    }
  },

  componentDidMount: function() {
    $.ajax({
      type: 'GET',
      url: '/api/blogPosts',
      success: function(data) {
        this.setState({posts: data});
      }.bind(this)
    })
  },

  handleSubmit: function() {

    event.preventDefault();

    var blogPost = this.state.postbody;

    $.ajax({

      type: 'POST',
      url: '/api/blogPosts',
      data: { postbody: blogPost },
      success:function(){
          this.setState({posts: Object.assign([],this.state.posts.push({postbody:postbody}))});  
      }.bind(this)
    });

  },

  handleChange: function(event) {

    this.setState({ postbody: event.target.value})
  },

  render: function() {
    return (
      <div>
        <form action="/api/blogPosts" method="post" onSubmit={this.handleSubmit}>
            <input onChange={this.handleChange} type="text" name="postbody"></input>
            <input type="submit" value="Submit" >Submit</button>
        </form>
        <List array={this.state.posts} />
      </div>
    )
  }
})

这个想法是你维护一个商店,它存在于组件之外,你通过各种事件/动作来管理商店。在这种情况下,应用程序相对简单,所以我们可以负担得起&#34; store&#34;作为国家道具并通过POST XHR进行更改。

但是,随着您的应用逻辑不断增加,请在商店中添加帖子数据。并将CRUD数据操作到商店中。并在商店中添加一个侦听器,以使用状态变量发布React组件的更新并更新它。

每当商店中的某些内容发生变化时,请使用侦听器(在商店,组件和api调用之间来回传递数据)和组件更新来更改商店内的状态变量。这就是Flux的工作原理。还有其他方法可以做到这一点。只是一个开始。