编辑答案:
我没有在此处发布所有步骤,但您需要遵循与项目集合完全相同的步骤,但对于您的子项目集合,因此制作您的子项目减速器,将其添加到 rootReducer...等,以便子项目处于全局状态,您可以将它们链接到您的组件,就像您对项目集合所做的那样。
您需要定义它是否在单独的减速器中,在项目减速器本身中,以便它处于如下状态:const subprojects = state.firestore.data.projects.subprojects;
要编写您的连接器,您需要查看redux-firestore repo,它建议如何连接子集合。检查示例:
{
collection: 'cities',
doc: 'SF',
subcollections: [{ collection: 'zipcodes' }],
storeAs: 'SF-zipcodes' // make sure to include this
},
也就是说,mapStateToProps 如下:
const mapStateToProps = (state, ownProps) => {
// console.log(state);
const id = ownProps.match.params.id;
const subprojects = state.firestore.data.projects.subprojects;
const subproject = subproject ? subproject [id] : null
return {
subproject : subproject
}
}
export default compose(
connect(mapStateToProps),
firestoreConnect([{
collection: 'projects',
doc: 'YourDoc'
subcollections: [{ collection: 'subprojects' }],
storeAs: 'YorDoc-subprojects'
}])
)(YourSubProjectsComponent)
没有调试过的代码,只是基于 repo 示例的建议,以防对您继续前进有帮助。
另一方面,如果有任何帮助,请在projectDetails 组件的代码下方找到,使用useState 挂钩从firestore 中获取确定的项目。对于您的具体情况,我相信它会以相同的方式应用,但查询您的 subprojects 集合。 (打字稿代码)。我发布这个,以防万一您可能在“手动”获取您的集合之后,而不是直接与 redux 绑定。如果你想要的是直接绑定你的子项目集合的 redux,你可以省略下面的代码。
import { IFirebaseProject } from '../../store/types/projectTypes';
import { Redirect } from 'react-router-dom';
import moment from 'moment';
import firebase from 'firebase/app';
import { useState } from 'react';
async function getFbProject(id: string) {
const db = firebase.firestore();
const fbDoc = db.collection("projects").doc(id);
let project = {} as IFirebaseProject;
await fbDoc.get().then(function(doc) {
if (doc.exists) {
console.log("Document data:", doc.data());
project = { ...doc.data()} as IFirebaseProject;
} else {
console.log(`Document does not exist ${id}`);
}
}).catch(function(error) {
console.log(`Error getting document: ${id}`, error);
});
return project;
}
function getProjectId():string {
const pathStr = window.location.pathname.toString();
const parts = pathStr.split("/");
const projStrIndex = parts.indexOf('project');
const projectId = parts[projStrIndex + 1];
return projectId;
}
const ProjectDetails = ({ project }: { project: IFirebaseProject } | { project: undefined }) => {
const [stateProject, setStateProject] = useState<IFirebaseProject | undefined>(project);
if (!firebase.auth().currentUser) return <Redirect to='/'/>
if (stateProject) {
return(
<div className="container section project-details">
<div className="card z-depth-0">
<div className="card-content">
<span className="card-title">{stateProject.title}</span>
<p>
{stateProject.content}
</p>
</div>
<div className="card-action grey lighten-4">
<div>{stateProject.authorFirstName} {stateProject.authorLastName}</div>
<div>{moment(stateProject.createdAt.toDate()).calendar()}</div>
</div>
</div>
</div>
)
} else {
//fetch project
const projectId = getProjectId();
getFbProject(projectId).then((project) => {
if (project) {
setStateProject(project);
}
});
return(
<div>
<p> Loading project... </p>
</div>
)
}
}
export default ProjectDetails;