簡體   English   中英

如何在 React 中從另一個組件重新渲染一個組件?

[英]How can I re-render one component from another component in React?

我有一個帶有創建帖子的表單的組件,然后我有另一個在提要中顯示這些帖子的組件。 創建新帖子時如何讓提要重新呈現? 最好的方法是什么?

  1. 在不更改道具的情況下重新渲染父組件?
  2. 更新道具?
  3. 還有什么辦法?

創建.js

import React, { useState } from "react";

export default function Create () {
    const [form, setForm] = useState({
      post: "",
    });

    // These methods will update the state properties.
    function updateForm(value) {
        return setForm((prev) => {
        return { ...prev, ...value };
        });
  }

  async function onSubmit(e) {
      e.preventDefault();

    // When a post request is sent to the create url, we'll add a new post to the database.
    const newPost = { ...form };

    await fetch("http://localhost:3000/post/add", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(newPost),
      })
      .catch(error => {
        window.alert(error);
        return;
      });
  
      setForm({ post: "" });
  }

  

  return (
      <div>
        <form onSubmit={onSubmit}>
            <div className="form-group">
            <label htmlFor="post">Post</label>
            <input
                type="text"
                className="form-control"
                id="post"
                value={form.post}
                onChange={(e) => updateForm( { post: e.target.value })}
            />
            </div>
            <div className="form-group">
            <input
                type="submit"
                value="Create post"
                className="btn btn-primary"
            />
            </div>
          </form>
        </div>
    );
}

Feed.js

import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";

const Post = (props) => (
    <div>
        {props.post.post}
            <Link className="btn btn-link" to={`/edit/${props.post._id}`}>Edit</Link>
              <button className="btn btn-link" onClick={() => { props.deletePost(props.post._id);
            }}
            >
        Delete
      </button>
    </div>
);

export default function PostList() {
    const [posts, setPosts] = useState([]);
  
    // This method fetches the posts from the database.
    useEffect(() => {
      async function getPosts() {
        const response = await fetch(`http://localhost:3000/post/`);
  
        if (!response.ok) {
          const message = `An error occured: ${response.statusText}`;
          window.alert(message);
          return;
        }
  
        const posts = await response.json();
        setPosts(posts);
      }
  
      getPosts();
  
      return; 
    }, [posts.length]);
  
    // This method will delete a post
    async function deletePost(id) {
      await fetch(`http://localhost:3000/${id}`, {
        method: "DELETE"
      });
  
      const newPosts = posts.filter((el) => el._id !== id);
      setPosts(newPosts);
    }
  
    // This method will map out the posts on the table
    function postList() {
      return posts.map((post) => {
        return (
          <Post
            post={post}
            deletePost={() => deletePost(post._id)}
            key={post._id}
          />
        );
      });
    }
  
    // This following section will display the the posts.

    return (
      <div>
        <h3>Post List</h3>
        <div>{postList()}</div>
      </div>
    );
  }

主頁.js

import React from "react";
import Feed from "./feed";
import Create from "./create";


const Home = () => {  

  return (
    <div className="app">
      <div>
        <Create />
        <Feed />
      </div>
    </div>
  );
};

export default Home;

有很多方法可以做到這一點。 您應該從最直接的開始:將您當前的帖子和 setPosts 從父組件傳遞到兩個組件中:

const Parent = () => {
  const [posts, setPosts] = useState([]);
  return <>
    <Create posts={posts} setPosts={setPosts} />
    <PostList posts={posts} setPosts={setPosts} />
  </>
}

有更好的方法可以做到這一點,但它們的參與度更高。 我建議你從這個開始,以了解 React 如何更好地處理數據。

暫無
暫無

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

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