简体   繁体   English

ReactJS-如何构造组件以刷新数据块?

[英]ReactJS - how to structure components to refresh a block with data?

I am starting playing with React and trying to build a simple app where I have a list of posts and after adding a new one, this post would be added to the list. 我开始玩React,并尝试构建一个简单的应用程序,在其中有一个帖子列表,并在添加新帖子后将该帖子添加到列表中。 Here's what I have so far: 这是我到目前为止的内容:

import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
import Moment from 'react-moment';
import LoadModal from './LoadModal';
import NewPost from './NewPost';

class Posts extends React.Component {
    constructor(props) {
        super(props);

      this.state = {
        posts: [],
            loading: true
       };
    }

    componentDidMount() {
        axios.get('/posts')
        .then(response => {
            this.setState({ posts: response.data, loading: false });
          });
    }

    toggleItem(index) {
        console.log('clicked index: '+index);
        this.setState({
            activeKey: this.state.activeKey === index ? null : index
        })
    }

    moreLess(index) {
        if (this.state.activeKey === index) {
            return (
                <span>
                    <i className='fas fa-angle-up'></i> Less
                </span>
            );
        } else {
            return (
                <span>
                    <i className='fas fa-angle-down'></i> More
                </span>
            );                      
        }
    }


  render () {
        let content;

        if (this.state.loading) {
            content = 'Loading...';
        } else {
            content = this.state.posts.map(post => {
            return(
                <li key={post.id}>
                <div>   
                            <span>{post.id}</span>
                            <i className="fas fa-clock"></i>
                            <Moment format="MMM DD @ HH:MM">
                                <span className="badge badge-pill badge-primary">{post.created_at}</span>
                            </Moment>
                            <button className="btn btn-primary btn-xs" style={{'marginLeft': '10px'}} onClick={this.toggleItem.bind(this, post.id)}>
                                {this.moreLess(post.id)}
                            </button>
                        </div>
                        <div className={this.state.activeKey === post.id ? "msg show" : "msg hide"}>{post.message}</div>
                    </li>
                )
            });
        }
    return (
            <div>
        <h1>Posts!</h1>
                <div className="row">
                    <NewPost />
                </div>
                <div className="row">
                    <div className="col-md-6">
                        <ul>
                            {content}
                        </ul>
                    </div>
                    <div className="col-md-6">
                        <div>
                    Modal
                        </div>
                    </div>
                </div>
      </div>
    );
  }
}

export default Posts

and

import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';

class NewPost extends React.Component {
    constructor(props) {
        super(props);
        this.state = { 
            namee: '',  
            description: '' 
        }

        this.handleChangeNamee = this.handleChangeNamee.bind(this);
        this.handleChangeDescr = this.handleChangeDescr.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);   
    }

    handleChangeNamee(event) {                  
      this.setState({
            namee: event.target.value
        });
    }
    handleChangeDescr(event) {          
      this.setState({
            description: event.target.value
        });
    }

    handleSubmit(event) {
      event.preventDefault();           
        const form_data = {
      namee: this.state.namee,
            description: this.state.description
    };

        axios.post('/posts/testtt', { form_data })
              .then(res => {
                console.log(res);
                console.log(res.data); // here, I can see added the new post along with the old ones. How is that possible?
                Posts.setState({ posts: response.data, loading: false });

              })
    }

  render () {
    return (
      <div style={{'marginBottom': '20px'}}>
                <form onSubmit={this.handleSubmit}>
                    <input name='namee' value={this.state.namee} onChange={this.handleChangeNamee}  />
            <input name='description' value={this.state.description} onChange={this.handleChangeDescr}  />
            <button onClick={this.handleItem}>Submit</button>
                </form>
      </div>
    );
  } 
}
export default NewPost

I am adding the posts to the database on a Rails backend: 我将帖子添加到Rails后端的数据库中:

def testtt
    Post.create(message: params[:form_data][:description])
    @posts = Post.order('created_at')
    render json: @posts
  end

What I struggled on - I added a new post to the database, but - how do I add this new post to the list of existing ones? 我苦苦挣扎的是-我向数据库中添加了一个新帖子,但是-如何将该新帖子添加到现有帖子列表中?

EDIT: Adding also my index.html.erb (it's only rendering there the components). 编辑:还添加了我的index.html.erb (它仅在此处呈现组件)。

<%= react_component('Header', {title: 'Radek'}) %>

<%= react_component("HelloWorld", { greeting: "Hello" }) %>

<%= react_component("LoadModal") %>

<%= react_component("Posts") %>

First, I feel it is sor of overengineering to return all of the posts after create. 首先,我觉得在创建后退还所有帖子是过度工程的感觉。 So let's do something like: 因此,让我们做类似的事情:

@post = Post.new(params.require(:post).permit(:message))
if post.save
  render json: @post
else
  render json: @post.errors, status: :unprocessable_entity 
end

On front end try something like 在前端尝试类似

handleSubmit(event) {
  event.preventDefault();           
    const form_data = {
  namee: this.state.namee,
        description: this.state.description
};

    axios.post('/posts/testtt', { form_data })
          .then(res => {
            console.log(res);
            console.log(res.data); 
            this.props.onAddPost(res.data)

          })
}

in NewPost, having in mind to give it a prop onAddPost like <NewPost onAddPost={(e) => this.addPost(post, e)}/> with addPost defined like so: 在NewPost中,请记住给它一个onAddPost的道具,例如<NewPost onAddPost={(e) => this.addPost(post, e)}/>addPost定义addPost如下所示:

addPost(post){
    const oldPosts = this.state.posts;
    this.setState({posts: oldPosts.push(post)})
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM