React - 通过触发另一个组件中的事件来渲染一个组件



父组件连接到Google Cloud FireStore,并使用setCards钩子将所有数据保存到卡片中。

接下来,我们将两个子组件导入到我们的父组件中:

<UpdateCard card={card} />
<AddCard totalDoclNumbers={totalDoclNumbers} />

父组件 - 停靠列表

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,这正是我正在努力解决的问题。

我怎样才能实现点击添加卡组件内的按钮,触发更新卡组件中的渲染。

好的,所以首先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在需要时作为 props 传递给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为props,如果你想在单击添加按钮后在UpdateCard中做一些事情,你可以将useEffect[addButtonClickCount]依赖项数组一起使用。

相关内容

  • 没有找到相关文章

最新更新