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