如何使用 props 在另一个组件中使用 useState 函数?

How to use a useState function in another component with props?

我编写了一个 React.js 笔记 Web 应用程序,用户最多可以在其中添加 10 个笔记。

我使用 map() 来迭代音符数组,并使用 useState(1) 钩子来更新它的计数(音符的默认数量是 1),所以我想做这样的事情:

  {[...Array(noteCount)].map((_, i) => <Note onUpdateNoteCount={() =>setNoteCount(n => n - 1)} key={i} />)}

问题是 Note() 组件位于 Main() 组件内,该组件位于 App() 组件,所以我想获得所需的值作为 App() 的道具,然后在 Note(),但不知道怎么放,放在哪里。

谢谢!

App.js

  import React from 'react';
  import Header from './Header';
  import Main from './Main';
function App () {
  const [noteCount, setNoteCount] = React.useState(1);
  function multiplyNoteComponent () {
    if (noteCount < 20) {
      setNoteCount(n => n + 1)
    }
    else {
      alert('too many notes. remove or combine some of them together!')
    }
  }
  return (
    <div>
      <Header/>
      {[...Array(noteCount)].map((_, i) => <Main onUpdateNoteCount={() =>setNoteCount(n => n - 1)} key={i} />)}

      <button
            style={{left: '5%'}}
          id='addNoteBtn'
          onClick={multiplyNoteComponent}
          title='Add a note'
         >
        +
      </button>
    </div>
  );
}
  export default App;

Main.js

    import React from 'react';
    import Note from './Note';
function Main () {
    return (
        <main>
            your notes are:
            <Note/>
        </main>
    )
}
    export default Main;

Note.js

    import React from 'react';
function Note () {
    return (
        <div> <button title='delete note' onClick={}>X</delete>
            <li>
                <input type='text'/>
            </li>
        </div>
    )
}
    export default Note

编辑:我认为我需要在 Note() 组件中使用 setNoteCount() 函数的原因是为了在删除笔记时进行倒计时(每个笔记都有自己的删除按钮)。

我会推荐您应用程序的这种架构。

  1. Notes 数组存储在 App 层。
  2. 使用 NoteInput 添加注释,这会向 Notes 数组添加注释。
  3. 使用 Note 组件映射您的 Notes,该组件将 onDelete 作为 App 级别的道具。
  4. 您的 App 组件应该负责存储和删除状态中的注释。

在您的示例中,notesCount 表示派生状态。 即它可以简单地从 Notes 数组 (notes.length).

派生

因此,与其存储 notesCount,我建议存储注释并从中导出计数。

您可以在此处查看工作示例:- https://stackblitz.com/edit/react-g19tei

import React from "react";
import "./style.css";

const NOTES_ALLOWED = 10;

export default function App() {
  const [notes, setNotes] = React.useState([]);

  function addNote(newNote) {
    if (notes.length === NOTES_ALLOWED) {
      alert(`Only ${NOTES_ALLOWED} notes are allowed to be added`)
    } else {
      setNotes([...notes, newNote]);
    }
  }

  function handleDelete(deleteNoteIdx) {
    const newNotes = [...notes];
    // delete the note at the specific index
    newNotes.splice(deleteNoteIdx, 1)
    setNotes(newNotes);
  }

  return (
    <div>
      <div style={{ marginTop: 20, marginBottom: 20 }}>
        <p>Your notes are</p>
        {notes.map((note, idx) => ( 
          <Note 
            note={note} 
            onDelete={() => handleDelete(idx)} 
          />
        ))}
      </div>
      <NoteInput onAdd={addNote} />
    </div>
  );
}

function Note({ note, onDelete }) {
  return (
    <div>
     <p>{note}
      <button onClick={onDelete}>Delete Note</button>
     </p>
    </div>
  )
}

function NoteInput({ onAdd }) {
  const [note, setNote] = React.useState('');

  function handleSubmit(e) {
    e.preventDefault();
    const noteToBeSend = note;
    setNote('')
    onAdd(noteToBeSend.trim());
  }

  return (
    <div>
     <form onSubmit={handleSubmit}>
        <input 
          type="text" 
          value={note}
          onChange={e => setNote(e.target.value)}
          required
        />
        <button type="submit">Add Note</button>
      </form>
    </div>
  )
}