为什么组件的状态会被删除的组件填充?

问题描述 投票:0回答:1

我正在制作一个 React 项目,并且很奇怪为什么我的组件 NoteComponent 我不每次都删除更改。我是 React 新手,不明白它是如何正确工作的。

如果有人可以提供建议,我将为您的经历感到非常高兴。谢谢你。

我有父组件“NotesWorkflow”:

import React, { Component, ReactNode } from "react";
import { CurrentNote, Note } from "../../interfaces/Note.interface";
import { List } from "../../components/list/List";
import { ListProps } from "../../interfaces/list/ListProps.interface";
import { NoteComponents } from "../../services/createComponents";
import { DashboardState } from "../../interfaces/dashboard/DashboardState";
import { getAllMessages } from "../../services/requests";
import { NewNoteComponent } from "../../components/note/NewNoteComponent";

export class NotesWorkflow extends Component<
  {},
  CurrentNote &
    DashboardState & { notes: Note[] } & {
      NewNoteComponentBlockOpened: boolean;
    }
> {
  state = {
    notes: [],
    currentId: "",
    NewNoteComponentBlockOpened: false,
  };
  componentDidMount = async () => {
    this.setState({
      notes: await getAllMessages(),
    });
  };

  createNewComponent = async () => {
    this.setState({
      NewNoteComponentBlockOpened: true,
    });
  };

  render(): React.ReactNode {
    const { notes } = this.state;

    return (
      <div className="dashboard__panel">
        <div className="dashboard__list">
          <input
            type="text"
            className="dashboard__search"
            placeholder="&#128269;"
          />
          <List
            notes={notes as ListProps[]}
            selectNote={(id) => {
              this.setState({ currentId: id });
            }}
            currentId={this.state.currentId}
          />
        </div>
        <div className="dashboard__notes__wrapper">
          <button
            className="note__button__addNew"
            onClick={this.createNewComponent}
          >
            Create a Note
          </button>
          {this.state.NewNoteComponentBlockOpened ? (
            <NewNoteComponent
              closeNote={() => {
                this.setState({ NewNoteComponentBlockOpened: false });
              }}
              addNewNoteDashboard={async (note) => {
                this.setState(({ notes }) => {
                  const oldNotesCopy = notes.slice();
                  oldNotesCopy.push(note);
                  return { notes: oldNotesCopy };
                });
              }}
            />
          ) : (
            ""
        )}
------------- HERE IS CREATING NOTES !!!!_!!!!_!!!!_!!!!
          {NoteComponents(notes, {
            selectNote: (id) => {
              this.setState({ currentId: id });
            },
            deleteNote: (id: string) => {
              const filtered = this.state.notes.filter((v: Note) => {
                console.log(`
                  ${v.id} =? ${id} =
                  ${v.id === id}`);
                return v.id !== id;
              });
              this.setState({
                notes: filtered,
                currentId: "",
              });
            },
            currentId: this.state.currentId,
          })}
        </div>
      </div>
    );
  }
}

“NoteComponents”功能:

import { NoteComponent } from "../components/note/NoteComponent";
import { Note } from "../interfaces/Note.interface";
import { NoteProperties } from "../interfaces/noteComponent/NoteProperties.interface";

export const NoteComponents = (
  notes: Note[],
  noteProperties: Omit<NoteProperties, "note">
) => {
  return notes.map((v, i) => {
    return (
      <NoteComponent
        key={i}
        selectNote={noteProperties.selectNote}
        currentId={noteProperties.currentId}
        note={v}
        deleteNote={noteProperties.deleteNote}
      />
    );
  });
};

还有“NoteComponent”:

import React, { Component, ReactDOM } from "react";
import { NoteProperties } from "../../interfaces/noteComponent/NoteProperties.interface";
import { Note, PrevState } from "../../interfaces/Note.interface";
import { patchNote, deleteCurrentNote } from "../../services/requests";

export class NoteComponent extends Component<
  NoteProperties,
  Omit<Note, "id"> & PrevState
> {
  mainRef: React.RefObject<HTMLDivElement> = React.createRef<HTMLDivElement>();
  state: Readonly<Note & PrevState> = {
    ...this.props.note,
    prevState: this.props.note,
  };

  openNote = () => {
    const { id } = this.props.note;
    this.props.selectNote(id);
    this.mainRef.current?.classList.remove("closedClass");
  };

  closeNote = () => {
    this.props.selectNote("");
    this.mainRef.current?.classList.add("closedClass");
  };

  updateNote = async () => {
    const note: Note = {
      id: this.props.note.id,
      text: this.state.text,
      title: this.state.title,
    };

    const response: Note = await patchNote(note);

    const newState: Note & PrevState = {
      ...response,
      prevState: {
        ...response,
      },
    };

    this.setState(newState);
    this.closeNote();
  };

  deleteNote = async () => {
    const { id } = this.props.note;
    await deleteCurrentNote(id);
    this.props.deleteNote(id);
  };

  handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
    event.preventDefault();
    const { currentTarget } = event;
    const name = currentTarget.getAttribute("name");
    if (name === "title") {
      this.setState({ title: currentTarget.value });
    } else {
      this.setState({ text: currentTarget.value });
    }
  };

  render() {
    const { currentId, note } = this.props;
    const isOpened = currentId === note.id;
    const TextAreas = () => {
      if (!isOpened) {
        return (
          <>
            <h3>{this.state.prevState.title}</h3>
            <p>{this.state.prevState.text}</p>
          </>
        );
      }
      return (
        <>
          <textarea
            name="title"
            className="note__title"
            value={this.state.title}
            onChange={this.handleChange}
          />
          <textarea
            name="text"
            className="note__text"
            value={this.state.text}
            onChange={this.handleChange}
          />
        </>
      );
    };

    return (
      <div className={"note__wrapper " + (isOpened ? "openedClass" : "")}>
        <div
          className={"note " + (isOpened ? "" : "closedClass")}
          ref={this.mainRef}
          onClick={this.openNote}
        >
          <button className="note__close" onClick={this.closeNote}>
            x
          </button>
          <div className="note__content">{TextAreas()}</div>
          <div className="note__buttons">
            <button onClick={this.updateNote}>SAVE</button>
            <button onClick={this.deleteNote}>DELETE</button>
          </div>
        </div>
      </div>
    );
  }
}

当我使用deleteNote函数删除当前注释时,我不删除的注释会更改为已删除注释的标题和文本(但不是id)

这是一个例子:

创建了 3 个笔记

删除标题为“2”的注释并查看结果

删除了标题为“2”的注释,并将标题为“3”的注释替换为标题“2”

毕竟我们可以看到变化,并且 3 个注释与其自身不对应,但注释的 id 是正确的。

重新加载页面后:

标题为“3”的注释现在是正确的

可能是什么?请问,我对 setState 有什么不明白的地方?

我尝试再次请求回调中的所有笔记并从头开始获取所有笔记,但它没有给我我期望的结果

reactjs typescript
1个回答
0
投票

问题出在key属性上,每次填新的id,都不一样。所以我将密钥从 key={i} 更改为 key={note.id} 。所以我知道这是一样的

© www.soinside.com 2019 - 2024. All rights reserved.