reactjs - 从firestore中删除数据时渲染react-redux功能组件时出错(useFirestoreConnect)
问题描述
当我第一次加载应用程序时,我ArticleList
的组件已成功获取并显示来自 firestore 的用户文章列表。用户可以点击“Remove Article”按钮,成功将文章从firestore的子集合中移除,但是却导致react组件渲染出错,似乎还在尝试渲染刚刚移除的文章,现在为空。我还能做些什么来让我的反应组件不断地监听 firestore 数据吗?如果可能的话,我想保留它一个功能组件并使用钩子而不是让它成为一个类,但我仍在学习如何使用反应钩子,因此有点挣扎。
ArticleList
零件:
const ArticleList = (props) => {
const firestore = useFirestore();
const userId = props.auth.uid;
useFirestoreConnect([
{
collection: 'users',
doc: userId,
subcollections: [{collection: 'articles'}],
storeAs: userId + '::articles'
}
]);
const myArticles = useSelector(state => state.firestore.data[`${userId}::articles`]);
const dispatch = useDispatch();
const removeArticle = useCallback(
articleId => dispatch(removeArticleFromFirebase({ firestore }, articleId)),
[firestore]
);
if (props.auth.uid) {
return(
<div>
<h3>My Articles</h3>
<p>Currently signed in: {props.auth.email}</p>
<br/>
{myArticles ? (
Object.keys(myArticles).map(articleId => {
let article = myArticles[articleId];
let articleInformation = '';
if (articleId === props.currentPaperId) {
articleInformation =
<div>
<p>{article.year}</p>
<p>{article.description}</p>
<a target="_blank" href={article.downloadUrl}><button className='waves-effect waves-light btn-small'>See article</button></a>
<button className='waves-effect waves-light btn-small' onClick={() => {removeArticle(articleId);}}>Remove from My Articles</button>
</div>;
}
let authorName = '';
if (article.author) {
authorName = ` by ${article.author}`;
}
if (article) {
return <span key={articleId}>
<li onClick={() => {dispatch(selectArticle(articleId));}}>
<em>{article.title}</em>{authorName}
</li>{articleInformation}
</span>;
} else {
return null;
}
})
) : (
<h4>No articles yet</h4>
)
}
</div>
);
} else {
return null;
}
};
const mapStateToProps = (state) => {
return {
currentPaperId: state.currentPaperId,
auth: state.firebase.auth
};
};
export default compose(connect(mapStateToProps))(ArticleList);
和removeArticleFromFirebase
行动:
export const removeArticleFromFirebase = ({ firestore }, id) => {
return (dispatch, getState) => {
const userId = getState().firebase.auth.uid;
firestore
.collection('users')
.doc(userId)
.collection('articles')
.doc(id)
.delete()
.then(() => {
console.log('Deleted article from firestore: ', id);
dispatch({ type: 'REMOVE_ARTICLE', id });
})
.catch(err => {
console.log('Error: ', err);
});
};
}
我尝试在下面添加useState
和(并尝试通过而不是通过组件的返回语句映射),但没有成功:useEffect
ArticleList
myArticlesState
myArticles
const [myArticlesState, setMyArticlesState] = useState(myArticles);
useEffect(() => {
setMyArticlesState(myArticles);
}, [myArticles]);
注意:我目前在整个应用程序状态/redux store/props 中根本没有这篇文章列表。这是我接下来要尝试的事情,但我决定先发布我的问题,以防我可以在这个组件中使用钩子。应用程序的其他组件/部分不需要访问此特定列表。
控制台错误: 错误图像 1 错误图像 2 Github repo:https ://github.com/jpremmel/yarp2.0
解决方案
很难看到发生了什么,但看起来好像您正在尝试在不存在的对象上使用属性。因此,检查这些属性应该有助于解决这个问题。
您可以尝试以下代码作为您的文章列表吗?
const ArticleList = (props) => {
const firestore = useFirestore();
const userId = props.auth.uid;
useFirestoreConnect([{
collection: 'users',
doc: userId,
subcollections: [{ collection: 'articles' }],
storeAs: userId + '::articles'
}]);
const myArticles = useSelector(state => state.firestore.data[`${userId}::articles`]);
const dispatch = useDispatch();
const removeArticle = useCallback(articleId => dispatch(removeArticleFromFirebase({ firestore }, articleId)), [firestore]);
if (props.auth.uid) {
return (
<div>
<h3>My Articles</h3>
<p>Currently signed in: {props.auth.email}</p>
<br />
{myArticles ? (
Object.keys(myArticles).map(articleId => {
let article = myArticles[articleId];
let articleInformation = '';
if (article) {
if (
articleId === props.currentPaperId &&
article.hasOwnProperty('year') &&
article.hasOwnProperty('description') &&
article.hasOwnProperty('downloadUrl')
) {
articleInformation =
<div>
<p>{article.year}</p>
<p>{article.description}</p>
<a target="_blank" href={article.downloadUrl}><button className='waves-effect waves-light btn-small'>See article</button></a>
<button className='waves-effect waves-light btn-small' onClick={() => { removeArticle(articleId); }}>Remove from My Articles</button>
</div>;
}
let authorName = '';
if (article.hasOwnProperty('author') && article.author) {
authorName = ` by ${article.author}`;
}
if (article.hasOwnProperty('title') && article.title) {
return <span key={articleId}>
<li onClick={() => { dispatch(selectArticle(articleId)); }}>
<em>{article.title}</em>{authorName}
</li>{articleInformation}
</span>;
} else {
return null;
}
}
})
) : (
<h4>No articles yet</h4>
)
}
</div>
);
} else {
return null;
}
};
const mapStateToProps = (state) => {
return {
currentPaperId: state.currentPaperId,
auth: state.firebase.auth
};
};
export default compose(connect(mapStateToProps))(ArticleList);
推荐阅读
- android - 启动反应本机运行android时出现持续错误
- c# - 如何按需运行后台服务——而不是在应用程序启动或计时器上
- python - 在 Python 的滚动表中显示实时股票数据
- android - 使用 RTP 和 h264 的 Android 的 GStreamer 管道问题
- typescript - Eslint 返回 no-unused-vars
- lotus-notes - Lotusscript:将文件从电子邮件转换为 base64 以 POST 方法发送
- python - 如何将代码更改为我输入的任何内容?
- python - 计算上一年的实例
- oauth - 访问共享邮箱的此类 oauth 令牌必须存在 ExchangeImpersonation SOAP 标头
- python - Assistance needed with this if/else: linear equation assignment for school