当我提交新笔记时,我需要重新加载页面才能看到新添加的数据.当我单击提交按钮时,我的控制台日志(log)中显示的唯一错误是这Warning: Each child in a list should have a unique "key" prop.

我正在try 理解useContext和useReducer挂钩.为了更好地理解代码,我只将代码保存在两个文件中.

如何在不重新加载页面的情况下查看新添加的备注,以及如何消除错误?

App.js:

import { useContext, useEffect, useState } from "react";
import { NoteProvider, NotesContext } from "./NoteContext";

export default function App() {
  return (
    <NoteProvider>
      <NotesList />
      <AddNewNote />
    </NoteProvider>
  );
}

function NotesList() {
  const { state, dispatch } = useContext(NotesContext);

  useEffect(() => {
    const getData = async () => {
      const res = await fetch("/api/note", {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
        },
      });
      const { data } = await res.json();
      console.log("data: ", data);
      dispatch({ type: "GET_NOTES", payload: { notes: data } });
    };

    getData();
  }, [dispatch]);

  return (
    <div>
      {state.notes.map((note) => {
        return (
          <div key={note._id}>
            <div>{note.title}</div>
          </div>
        );
      })}
    </div>
  );
}

function AddNewNote() {
  const { state, dispatch } = useContext(NotesContext);
  const [note, setNote] = useState("");

  const handleSubmit = async (e) => {
    e.preventDefault();

    const res = await fetch("/api/note", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ title: note }),
    });

    const data = await res.json()
    dispatch({ type: "ADD_A_NEW_NOTE", payload: { notes: data } });
  };

  const onChange = (e) => {
    setNote(e.target.value);
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <label>Note: </label>
        <input className="border" type="text" name="note" onChange={onChange} />
        <button className="border" type="submit">
          Submit
        </button>
      </form>
    </div>
  );
}

NoteConext.js:

import { createContext, useContext, useReducer } from "react";

export const NotesContext = createContext({
  notes: [],
});

export default function NotesReducer(state, action) {
  const actionPayload = action.payload;
  switch (action.type) {
    case "GET_NOTES":
      return {
        ...state,
        notes: actionPayload.notes,
      };

    case "ADD_A_NEW_NOTE":
      return {
        ...state,
        notes: [...state.notes, actionPayload]
      }

    default:
      return state;
  }
}

export function NoteProvider({ children }) {
  const initialState = useContext(NotesContext);

  const [state, dispatch] = useReducer(NotesReducer, initialState);

  return (
    <NotesContext.Provider value={{ state, dispatch }}>
      {children}
    </NotesContext.Provider>
  );
}

推荐答案

要在不重新加载页面的情况下查看新添加的笔记,您需要在发出POST请求后使用新笔记数据更新状态.目前,您正在从响应中分派整个数据对象,其中包含新添加的Note对象.但是,您应该只调度新添加的备注对象.

为此,您可以更新AddNewNote组件的handleSubmit函数,以仅调度新添加的Note对象:

const handleSubmit = async (e) => {
  e.preventDefault();

  const res = await fetch("/api/note", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ title: note }),
  });

  const { data } = await res.json();
  dispatch({ type: "ADD_A_NEW_NOTE", payload: { note: data.note } });

  setNote("");
};

在这里,您将分派一个"Add_A_New_Note"类型的新操作,其有效负载包含新添加的Note对象.您还将笔记状态变量重置为空字符串,以便在提交后清除输入字段.

关于

警告:列表中的每个子元素都应该有一个唯一的"关键"props .

您可以看到,它与NotesList组件中的map函数相关.呈现元素列表时,Reaction要求每个元素都有唯一的关键props .在您的例子中,您可以使用Note对象的_id字段作为关键props :

return (
  <div>
    {state.notes.map((note) => {
      return (
        <div key={note._id}>
          <div>{note.title}</div>
        </div>
      );
    })}
  </div>
);

通过使用_id字段作为关键props ,Reaction可以在状态更改时高效地更新笔记列表.

Reactjs相关问答推荐

在下一个js中使用ESTAccountWithEmailAndPassword函数时循环

每次单击按钮时,Reaction组件都会重新生成

如何使图像zoom 并移动到点击点

禁止直接访问Next.js中的页面,同时允许从应用程序内部访问

for each 子级加载父路由加载器

无法使用 Suspense 和 Await 获取数据

在reactjs中刷新页面时丢失状态值

在 golang 服务器中刷新或直接 url 路径时响应 404

Mui DataGrid 在第二页和前一页上显示项目时出现问题

从 redux 调用UPDATE_DATA操作时状态变得未定义

ReactJS on AWS Amplify与EC2上的Spring boot服务之间的混合内容错误

无法使axiosmockadapter正常工作

在 CrafterCMS Studio 中拖动字段

状态链接未传递到路由页面

更新 Next.js 路由查询更改的状态会导致无限循环

如何在 JSX 中使用 -webkit- 前缀?

如何根据react 中的 map 功能一次只打开一个弹出窗口?

为什么我在运行一些 npm react 命令时会收到这些警告?

将鼠标悬停在仅适用于该类的第一个实例的 p5.js 类上

为什么我不能使用 formik 更改此嵌套对象中的值