简体   繁体   English

React - 元素无法正确呈现

[英]React - Elements not rendering properly

I'm making a note taking app.我正在做一个笔记应用程序。 I have an array set to state that holds the notes and each note is set to state as an object.我有一个数组设置为 state 来保存音符,每个音符都设置为 state 作为一个对象。 My NoteList component maps over the array to render a new Note component when the save button is pressed.当按下保存按钮时,我的NoteList组件映射到数组上以呈现一个新的 Note 组件。 Everything works so far, except for the first note.到目前为止一切正常,除了第一个音符。 When the first note is saved, the delete button renders but not the user input or date.当第一个笔记被保存时,删除按钮呈现但不呈现用户输入或日期。 On every subsequent save, everything renders how it should.在随后的每次保存中,一切都会按照应有的方式呈现。 I've looked over my code but I'm not sure what is causing this.我查看了我的代码,但不确定是什么原因造成的。 Can someone please point me in the right direction?有人可以指出我正确的方向吗?

import { useState } from 'react';
import uniqid from 'uniqid';
import NoteList from './components/NoteList';

function App() {
  const [note, setNote] = useState({
    note: '',
    date: '',
    id: ''
  })
  const [notes, setNotes] = useState([])
  const [error, setError] = useState(false);

  function handleAddNote(text) {
    const date = new Date();
    const newNote = {
      text: text,
      date: date.toLocaleDateString(),
      id: uniqid()
    }
    setNote(newNote);
    const newNotes = [
      ...notes,
      note
    ]
    setNotes(newNotes);
  }

  return (
    <div className="App">
      <h1>My Notes</h1>
      <input placeholder='Type to search...'></input>
      <NoteList notes={notes} handleAddNote={handleAddNote}/>
   </div>
  );
}


export default App;

import Note from './Note'
import AddNote from './AddNote'

function NoteList({ notes, handleAddNote }) {
  return (
    <div className='list-container'>
      {notes.map((note) => (
        <Note text={note.text} id={note.id} date={note.date}          
                       key={note.id} notes={notes} note={note}/>
        ))}
        <AddNote handleAddNote={handleAddNote}/>
    </div>
  )
}

export default NoteList;

function Note({ note }) {
  return (
    <div className='note-container'>
      <span className='note-text'>{note.text}</span>
      <div className='note-footer'>
        <p className='note-date'>{note.date}</p>
        <button>Delete</button>
      </div>
    </div>
  )
}

export default Note;


import { useState } from 'react';

function AddNote({ handleAddNote } ) {
  const [noteText, setNoteText] = useState('');

  function handleChange(e) {
    setNoteText(e.target.value);
  }

  function handleSaveNote() {
    if (noteText) {
      handleAddNote(noteText);
      setNoteText('');
    }
  }

  return (
    <div className='new-note-container'>
        <textarea onChange={handleChange} value={noteText} 
          rows='5' cols='30' placeholder='Type to enter a note...'
         </textarea>        
        <div className='count-container'>
            <p>Character Count</p>
            <button onClick={handleSaveNote}>Save</button>
        </div>
      </div>
    )
  }

export default AddNote;

I think that the thing you are missing is that after calling setNote it does not change note on the current render.我认为你缺少的是在调用setNote之后它不会改变当前渲染的note Only in the next render for that component note will get the new state.只有在该组件note的下一次渲染中才会获得新状态。

In your case I don't see way you need to have a state for the new note so you can change your App component to be something like this:在您的情况下,我看不到您需要为新笔记设置状态的方式,因此您可以将 App 组件更改为如下所示:

function App() {
  const [notes, setNotes] = useState([])
  const [error, setError] = useState(false);

  function handleAddNote(text) {
    const date = new Date();
    const newNote = {
      text: text,
      date: date.toLocaleDateString(),
      id: uniqid()
    }
    setNotes((prevNotes) => [...prevNotes, newNote]);
  }

  return (
    <div className="App">
      <h1>My Notes</h1>
      <input placeholder='Type to search...'></input>
      <NoteList notes={notes} handleAddNote={handleAddNote}/>
   </div>
  );
}

All of these functions, such as adding notes, deleting notes, and searching for notes, are implemented in this code and work properly.所有这些功能,如添加笔记、删除笔记和搜索笔记,都在这段代码中实现并正常工作。 I think this might be helpful for you!我想这可能对你有帮助!

import { useState } from "react";
import { uuid } from "uuidv4";

const SelectChip = () => {
  const [notes, setNotes] = useState([]);
  const [searchTerm, setSearchTerm] = useState("");

  function handleAddNote(text) {
    const date = new Date();
    setNotes((prev) => [
      ...prev,
      {
        text: text,
        date: date.toLocaleDateString(),
        id: uuid()
      }
    ]);
  }

  return (
    <div className="App">
      <h1>My Notes</h1>
      <input
        value={searchTerm}
        onChange={(event) => setSearchTerm(event.target.value)}
        placeholder="Type to search..."
      />
      <NoteList
        notes={notes}
        setNotes={setNotes}
        handleAddNote={handleAddNote}
        search={searchTerm}
      />
    </div>
  );
};

export default SelectChip;

function NoteList({ notes, setNotes, handleAddNote, search }) {
  const filteredItems = notes.filter((item) =>
    item.text.toLowerCase().includes(search.toLowerCase())
  );

  return (
    <div className="list-container">
      {filteredItems.map((note) => {
        return (
          <Note
            text={note.text}
            id={note.id}
            date={note.date}
            key={note.id}
            setNotes={setNotes}
            note={note}
          />
        );
      })}
      <AddNote handleAddNote={handleAddNote} />
    </div>
  );
}

function Note({ note, setNotes }) {
  function handleDelete(noteId) {
    setNotes((prev) => prev.filter((note) => note.id !== noteId));
  }

  return (
    <div className="note-container">
      <span className="note-text">{note.text}</span>
      <div className="note-footer">
        <p className="note-date">{note.date}</p>
        <button onClick={() => handleDelete(note.id)}>Delete</button>
      </div>
    </div>
  );
}

function AddNote({ handleAddNote }) {
  const [noteText, setNoteText] = useState("");

  function handleChange(e) {
    setNoteText(e.target.value);
  }

  function handleSaveNote() {
    if (noteText) {
      handleAddNote(noteText);
      setNoteText("");
    }
  }

  return (
    <div className="new-note-container">
      <textarea
        onChange={handleChange}
        value={noteText}
        rows="5"
        cols="30"
        placeholder="Type to enter a note..."
      ></textarea>
      <div className="count-container">
        <p>Character Count</p>
        <button onClick={handleSaveNote}>Save</button>
      </div>
    </div>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM