如何使用 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() 函数的原因是为了在删除笔记时进行倒计时(每个笔记都有自己的删除按钮)。
我会推荐您应用程序的这种架构。
- 将
Notes
数组存储在 App
层。
- 使用
NoteInput
添加注释,这会向 Notes
数组添加注释。
- 使用
Note
组件映射您的 Notes
,该组件将 onDelete
作为 App
级别的道具。
- 您的
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>
)
}
我编写了一个 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() 函数的原因是为了在删除笔记时进行倒计时(每个笔记都有自己的删除按钮)。
我会推荐您应用程序的这种架构。
- 将
Notes
数组存储在App
层。 - 使用
NoteInput
添加注释,这会向Notes
数组添加注释。 - 使用
Note
组件映射您的Notes
,该组件将onDelete
作为App
级别的道具。 - 您的
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>
)
}