George_Fal 2015-11-19 23:16 采纳率: 0%
浏览 25

用React更新状态

I am creating a blog using React, MongoDB, Express and Node. I have three components: App, List, and Item. The item is a blog post; the list is a list of the blog posts, and the app includes a place to enter text and submit it. I will eventually add more functionality, but I want to determine if I am adhering to best practices for React (I doubt I am).

So in App, I getInitialState with an array of posts (posts) and a string of text for the input (postbody). I used the componentDidMount to make an AJAX GET request to my database, so the user can see all the posts.

To handle entering text I just made a simple handleChange function which updates the state of postbody.

I also have a handleClick function, which grabs this.state.postbody and then POSTs it database. However the same function also makes a separate GET request of the database to update the state of the posts array. This doesn't seem right! Shouldn't that be handled some other way and updated automatically? * This is the primary question I have. *

Also, please let me know if I need to break the components down further, or if I am violating best practices using React (e.g. changing state in the wrong place, or using props incorrectly).

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条回答 默认 最新

  • bug^君 2015-11-20 00:07
    关注

    Well, actually since you only have an Add api call, you could do this. You just push a blogPost to the array of posts in a post request. Also, you might want to use the form's 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>
        )
      }
    })
    

    The idea is that you maintain a store, which exists outside of the components and you manage the store through various events/actions. In this case, the app is relatively simple, so we can afford to have the "store" as a state prop and change it through the POST XHR.

    However, as your app logic keeps increasing, have the posts data in a store. And have actions CRUD data into the store. And add a listener on the store to publish updates to the React component and update it, using a state variable.

    Whenever something changes in the store, change the state variable from within the store using a listener(which passes data to and fro between stores,components and api calls) and your component updates. This is how Flux works. There are other ways to do this. Just a start.

    评论

报告相同问题?

悬赏问题

  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?