首页 > 解决方案 > 如何在另一个带有 props 的组件中使用 useState 函数?

问题描述

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

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

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

问题是Note()组件位于App ()组件中的Main()组件内,所以我想获取所需的值作为App()的道具,而不是在Note()中使用它们,但是无法弄清楚如何以及在哪里放置它。

谢谢!

应用程序.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;

主.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() 函数的原因是在删除笔记时倒计时(每个笔记都有自己的删除按钮)。

标签: arraysreactjsreact-hooksstateprop

解决方案


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

  1. Notes数组存储在App级别。
  2. 添加一个注释,使用NoteInput它将注释添加到您的Notes阵列。
  3. Notes使用从关卡作为道具的Note组件映射您。onDeleteApp
  4. 您的App组件应该负责存储和删除状态中的注释。

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

因此,notesCount我建议存储笔记并从中导出计数,而不是 storage 。

您可以在这里看到工作示例:- 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>
  )
}


推荐阅读