reactjs - React - 通过触发另一个组件中的事件来渲染一个组件
问题描述
父组件连接到 Google Cloud FireStore 并使用 setCards 挂钩将所有数据保存到卡片中。
接下来我们将两个子组件导入到我们的父组件中:
<UpdateCard card={card} />
<AddCard totalDoclNumbers={totalDoclNumbers} />
父组件 - DockList
import React, { useState, useEffect } from 'react';
import { db } from '../firebase';
import UpdateCard from './UpdateCard';
import AddCard from './AddCard';
const DocList = () => {
const [cards, setCards] = useState([]);
const [beginAfter, setBeginAfter] = useState(0);
const [totalDoclNumbers, setTotalDoclNumbers] = useState(0);
useEffect(() => {
const fetchData = async () => {
const data = await db
.collection('FlashCards')
.orderBy('customId')
.startAfter(beginAfter)
.get();
setCards(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
fetchData();
}, [beginAfter]);
return (
<ul className='list'>
{cards.map((card) => (
<li key={card.id} className='list__item' data-id={card.id}>
<UpdateCard card={card} />
</li>
))}
<AddCard totalDoclNumbers={totalDoclNumbers} />
</ul>
);
};
export default DocList;
在 UpdateCard 中,我们使用无序列表列出存储在卡片中的所有数据:
import React, { useState } from 'react';
import { db } from '../firebase';
const UpdateCard = ({ card }) => {
const [translatedText, setTranslatedText] = useState(card.translatedText);
const [customId, setCustomId] = useState(card.customId);
const onUpdate = async () => {
await db
.collection('FlashCards')
.doc(card.id)
.update({ ...card, customId, originalText, translatedText, imgURL });
};
return (
<>
<input
type='text'
value={customId}
onChange={(e) => {
setCustomId(Number(e.target.value));
}}
/>
<textarea
value={translatedText}
onChange={(e) => {
setTranslatedText(e.target.value);
}}
/>
<button onClick={onUpdate}>
Update
</button>
</>
);
};
export default UpdateCard;
最后,在名为AddCard的第二个子组件中,我们有一个按钮,它触发 onAdd 函数将新数据添加到我们的 FireStore 集合中。
import React, { useState } from 'react';
import { db } from '../firebase';
const AddCard = ({ totalDoclNumbers }) => {
const [newTranslatedText, setNewTranslatedText] = useState([]);
const nextNumber = totalDoclNumbers + 1;
const onAdd = async () => {
await db.collection('FlashCards').add({
translatedText: newTranslatedText,
customId: Number(nextNumber),
});
};
return (
<ul className='list'>
<li key={nextNumber}>
<input
type='text'
className='list__input'
defaultValue={nextNumber}
/>
<textarea
onChange={(e) => setNewTranslatedText(e.target.value)}
/>
<button onClick={onAdd}>
Add
</button>
</li>
</ul>
);
};
export default AddCard;
这一切都有效。当您单击第二个子组件AddCard组件内的按钮时,新数据将存储到集合中。
但是为了能够看到新添加的数据,我需要渲染UpdateCard,而这正是我正在努力解决的问题。
如何实现单击 AddCard 组件内的按钮,触发 UpdateCard 组件中的渲染。
解决方案
好的,所以首先DocList
添加一个回调函数:
const DocList = () => {
...
const [addButtonClickCount, setAddButtonClickCount] = useState(0);
...
return (
<ul className='list'>
{cards.map((card) => (
<li key={card.id} className='list__item' data-id={card.id}>
<UpdateCard card={card} addButtonClickCount={addButtonClickCount}/>
</li>
))}
<AddCard totalDoclNumbers={totalDoclNumbers} onAddButtonClick={(card) => {
setAddButtonClickCount(c => c + 1)
setCards(cards => [...cards, {...card.data(), id: card.idcard}])
}} />
</ul>
);
};
然后在需要时调用onAddButtonClick
它AddCard
作为道具传递:
const AddCard = ({ totalDoclNumbers, onAddButtonClick }) => {
...
const onAdd = async () => {
// Somehow you gotta get value of newly created card:
let card = await db.collection('FlashCards').add({
translatedText: newTranslatedText,
customId: Number(nextNumber),
});
// pass the newly created card here so you could use it in `UpdateCard`
onAddButtonClick(card) // this looks likes where it belongs.
};
这将导致UpdateCard
组件重新渲染,因为它作为道具获得,如果您想在单击添加按钮后addButtonClickCount
做某事,您可以使用依赖数组。UpdateCard
useEffect
[addButtonClickCount]
推荐阅读
- date - 在 Python 中从 CSV 读取和绘制日期
- ios - 将数据从集合视图单元格移动到新的集合视图单元格
- ios - 在 React Native 中从照片/图像中提取文本的最佳方法?
- c# - 为什么 int 步骤会改变?
- firebase - 如何在 Firebase 上创建自定义扩展?
- r - 提取 tiff 数据时出现模糊的警告消息
- unix - 获取最新修改的文件并从修改的文件中计算行数
- nestjs - 客户端是带有 NgRx-Data 的 Angular 8;服务器是 NestJs + MySQL。如何使用条件和 SQL 获取数据?
- postgresql - 执行函数 pg_ls_dir 的权限
- javascript - .then 链后变量被重置