簡體   English   中英

在 React 中顯示添加的帖子而不刷新頁面

[英]Show added posts without refreshing page in React

我一直在從事大學以外的個人項目,開發博客。 現在我正在嘗試實現一個“主頁”,在成功登錄后,用戶可以發布文本,然后它出現在 Create post div 下,您可以在圖片中看到這就是我設法完成的至今:

這是登錄后的首頁

現在我可以登錄並發布一個新帖子,將其保存在數據庫中。

這是用戶登錄后看到的 home.js 功能組件:

import '../App.css';    
import { useHistory } from "react-router-dom";
import React , {useState, useEffect} from 'react';
import jwt_decode from 'jwt-decode'
import logo from '../images/home-logo.png';
import {Col,Form,Input,Button,Card,CardTitle,Navbar,Nav,NavbarBrand} from 'reactstrap'
import { createPost,getUserPosts } from '../fucntions/user_functions'
function Home(){
    var _decoded;
    var _email;
    let history = useHistory();
    const[post_text,setPost] = useState('');

    const handleChangePost = e =>{ setPost(e.target.value);};


    function handlePost(e){
      e.preventDefault();
      const toPost = {
        post :post_text, email :_email
      }
      createPost(toPost).then(res =>{
        setPost('')
      })
    }

    function getPosts() {
      const container ={
        email:_email
      }
      getUserPosts(container).then(res=>{

      })
    }



    function handleLogout (e) {
        e.preventDefault();
        localStorage.removeItem('usertoken')  
        history.push(`/login`)
    }
    useEffect(() =>{
        if (localStorage.getItem("usertoken") === null) {
            history.push('/login')
        } else {
        const token = localStorage.usertoken
        const user_email = localStorage.useremail
        const decoded = jwt_decode(token)
        _decoded = decoded;
        _email = decoded.email
        getPosts()

    };
});
    return (
      <div className = "box">
        <div>
        <Navbar color="light" light expand="md">
                    <Nav>
                        <NavbarBrand type = "button" onClick = {handleLogout}>Logout</NavbarBrand>
                    </Nav>
        </Navbar>
        <div className = "wrapper">
           <Card body outline color="secondary" className = "card-home " >
            <CardTitle><img src={logo} alt="logo"></img>Create post</CardTitle>
            <Form onSubmit = {handlePost}>
            <Input  id = "tx" name = "input1" type = "textarea" value = {post_text} placeholder="Enter your post here"  onChange= {handleChangePost}></Input>
             <br></br>
            <Col sm={{ span: 10, offset: 5 }}>
              <Button outline color="primary" type="submit">Post!</Button>
            </Col>
            </Form>
           </Card>
          </div>
      </div>

    </div>

    )

}

export default Home;

我在后端實現了一個 getPosts 方法,它返回一個帖子數組

  router.post("/getPosts",
  async (req, res) => {
      const {email,} = req.body;
          try {
              let user = await User.findOne({email:email});
              allPosts = user.posts
             res.render('/home',{posts : hello})
        } catch (e) {
            console.error(e);
            res.json("Error")
      }
    }
);

As you can see above, in the function getPosts(), the response is an Array of all the post's ids the user has posted, they are stored in the mongodb collection called "posts" And after calling that function, I can iterate over them :

function getPosts() {
  const container ={
    email:_email
  }
  getUserPosts(container).then(res=>{
    forEach(res.posts) {

    }
  })
}

我想實時渲染所有這些帖子,所以每次用戶發布新帖子時,它都會顯示在您可以在圖片中看到的 Create post div 之后,最好的方法是什么? 謝謝

首先定義您的帖子集合 state:

const [allPosts, setAllPosts] = useState([]);

然后每次你在數據庫中成功保存一個帖子,append 它到那個 state:

function handlePost(e){
  e.preventDefault();
  const toPost = {
    post :post_text, email :_email
  }
  createPost(toPost).then(res =>{
    setPost('')
    setAllPosts(allPosts.concat(toPost);
  })
}

getPosts 也是如此:

   function getPosts() {
      const container ={
        email:_email
      }
      getUserPosts(container).then(res=>{
          setAllPosts(res.data); // <-- if the data is the same structure as the created before
      })
    }

然后您可以以示例方式呈現它們:

return (
  <div className = "box">
    <div>
      <Navbar color="light" light expand="md">
        <Nav>
          <NavbarBrand type = "button" onClick = {handleLogout}>Logout</NavbarBrand>
        </Nav>
      </Navbar>
      <div className = "wrapper">
        <Card body outline color="secondary" className = "card-home " >
          <CardTitle><img src={logo} alt="logo"></img>Create post</CardTitle>
          <Form onSubmit = {handlePost}>
            <Input  id = "tx" name = "input1" type = "textarea" value = {post_text} placeholder="Enter your post here"  onChange= {handleChangePost}></Input>
            <br></br>
            <Col sm={{ span: 10, offset: 5 }}>
              <Button outline color="primary" type="submit">Post!</Button>
            </Col>
          </Form>
          <div>
            {
              allPosts.map(post => {
                return <div><div>email: {post.email}</div><div>post: post.post</div></div>
              })
            }
          </div>
        </Card>
      </div>
    </div>

  </div>

)

隨意更改 HTML 結構,使其符合您的設計

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM