簡體   English   中英

如何從另一個組件更新或重新渲染一個組件? (反應)

[英]How can I update or re-render a component from another component? (React)

我最初通過 Routes 在兩個不同的頁面上顯示了兩個組件:RecordList 和 Create 組件。 當我使用 Routes 時,這一切目前都可以正常工作。 但是,我正在嘗試修改此項目,以便兩個組件同時位於同一頁面上,而不是位於兩個不同的頁面上。

我的目標是在單擊“添加記錄”按鈕后更新 RecordList(從服務器獲取數據)。 目前 Create 組件工作正常,但是我必須刷新頁面才能看到 RecordList 組件上的更改。

當記錄發布到服務器時,我無法理解要更新 RecordList 需要做什么。 任何指導都是有幫助的。

這是使用提升 State 的場景嗎? 我不這么認為,因為我相信這兩個組件是兄弟組件。

我需要重新渲染 RecordList 組件嗎? 我應該將這兩個組件組合成一個組件嗎? 我的猜測是,將它們作為兩個獨立的組件會更好。

作為參考,我沒有編寫所有這些代碼。 我正在嘗試修改我使用 MongoDB 網站上的 MERN 教程構建的項目。

這是頁面的截圖:主頁

應用程序.js:

import React from "react";
import './App.css';

// We use Route in order to define the different routes of our application
import { Route, Routes } from "react-router-dom";

// We import all the components we need in our app
import Navbar from "./components/navbar";
import RecordList from "./components/recordList";
import Edit from "./components/edit";
import Create from "./components/create";

const App = () => {
    return (
        <div>
            <div className="container">
                <Navbar />
            </div>
            <div className="container py-3 my-3 d-flex align-items-start justify-content-around flex-wrap flex-md-nowrap">

                <div className="w-100 px-md-3 py-3 py-md-0"><RecordList /></div>
                <div className="w-100 px-md-3 py-3 py-md-0"><Create /></div>
                {/* <Routes>
                    <Route exact path="/" element={<RecordList />} />
                    <Route path="/edit/:id" element={<Edit />} />
                    <Route path="/create" element={<Create />} />
                </Routes> */}
            </div>
        </div>
    );
};

export default App;

記錄列表.js:

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

const Record = (props) => (
    <tr>
        <td>{props.record.date}</td>
        <td>{props.record.destination}</td>
        <td>{props.record.location}</td>
        <td>
            <Link className="btn btn-link" to={`/edit/${props.record._id}`}>Edit</Link> |
            <button className="btn btn-link"
                onClick={() => {
                    props.deleteRecord(props.record._id);
                }}
            >
                Delete
            </button>
        </td>
    </tr>
);

export default function RecordList() {
    const [records, setRecords] = useState([]);

    // This method fetches the records from the database.
    useEffect(() => {
        async function getRecords() {
            const response = await fetch(`http://localhost:5000/record/`);

            if (!response.ok) {
                const message = `An error occurred: ${response.statusText}`;
                window.alert(message);
                return;
            }

            const records = await response.json();
            setRecords(records);
        }

        getRecords();

        return;
    }, [records.length]);

    // This method will delete a record
    async function deleteRecord(id) {
        await fetch(`http://localhost:5000/${id}`, {
            method: "DELETE"
        });

        const newRecords = records.filter((el) => el._id !== id);
        setRecords(newRecords);
    }

    // This method will map out the records on the table
    function recordList() {
        return records.map((record) => {
            return (
                <Record
                    record={record}
                    deleteRecord={() => deleteRecord(record._id)}
                    key={record._id}
                />
            );
        });
    }

    // This following section will display the table with the records of individuals.
    return (
        <div>
            <h3>Record List</h3>
            <table className="table table-striped" style={{ marginTop: 20 }}>
                <thead>
                    <tr>
                        <th>Date</th>
                        <th>Destination</th>
                        <th>Location</th>
                        <th>Action</th>
                    </tr>
                </thead>
                <tbody>{recordList()}</tbody>
            </table>
        </div>
    );
}

創建.js:

import { useNavigate } from "react-router";

export default function Create() {
    const [form, setForm] = useState({
        date: "",
        destination: "",
        location: "",
    });
    const navigate = useNavigate();

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

    // This function will handle the submission.
    async function onSubmit(e) {
        e.preventDefault();

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

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

        setForm({ date: "", destination: "", location: "" });
        navigate("/");
    }

    // This following section will display the form that takes the input from the user.
    return (
        <div>
            <h3>Add Mileage Record</h3>
            <form onSubmit={onSubmit}>
                <div className="row my-3">
                    <div className="col">
                        <div className="form-group">
                            <label htmlFor="date">Date</label>
                            <input
                                type="text"
                                className="form-control"
                                id="date"
                                value={form.date}
                                onChange={(e) => updateForm({ date: e.target.value })}
                            />
                        </div>
                    </div>
                    <div className="col">
                        <div className="form-group">
                            <label htmlFor="destination">Destination</label>
                            <input
                                type="text"
                                className="form-control"
                                id="destination"
                                value={form.destination}
                                onChange={(e) => updateForm({ destination: e.target.value })}
                            />
                        </div>
                    </div>
                </div>
                <div className="row my-3">
                    <div className="col">
                        <div className="form-group">
                            <label htmlFor="location">Location</label>
                            <input
                                type="text"
                                className="form-control"
                                id="location"
                                value={form.location}
                                onChange={(e) => updateForm({ location: e.target.value })}
                            />
                        </div>
                    </div>
                    <div className="row my-3">
                        <div className="col">
                            <div className="form-group">
                                <input
                                    type="submit"
                                    value="Add Record"
                                    className="btn btn-primary"
                                />
                            </div>
                        </div>
                    </div>
                </div>
            </form>
        </div>
    );
}

你有幾種方法可以解決這個問題:

  1. 您可以將記錄 state 從recordList移動到App並將記錄傳遞給recordList組件並傳遞 setRecords 以作為道具create組件,因此您可以在http://localhost:5000/record/add的 statusCode 為 200 時更新記錄。

  2. 您可以使用諸如 redux、redux-toolkit、jotai 等 stateManagement 包來管理整個應用程序端的更改

  3. 您可以使用保存記錄的上下文來訪問應用程序中各處的記錄。

  4. 您可以使用react-query package 一起管理獲取和保存數據。 您可以react-query-useful-hooks以優化和更輕松地使用 rickett

暫無
暫無

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

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