繁体   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