如何复用React组件适配Firebase不同数据库集合
通用MediaInput组件实现方案
- 前置注意点:Firebase初始化全局仅需执行一次,不要在每个组件构造函数中重复执行,否则会触发重复初始化报错,建议要么移到项目入口文件执行,要么在组件初始化时增加已初始化判断。
完整组件代码实现
class MediaInput extends React.Component { constructor(props) { super(props); // 避免Firebase重复初始化 if (!firebase.apps.length) { firebase.initializeApp(config); } // 取传入的type作为集合标识 this.collectionType = props.type; // 动态初始化对应集合的状态 this.state = { [this.collectionType]: [] }; } componentDidUpdate(prevProps, prevState) { // 仅当对应集合内容变化时触发写入操作,避免无效提交 if (prevState[this.collectionType] !== this.state[this.collectionType]) { this.writeUserData(); } // 若存在动态切换type的需求,可增加以下逻辑,固定传type的场景可省略 if (prevProps.type !== this.props.type) { this.collectionType = this.props.type; this.setState({ [this.collectionType]: [] }); } } writeUserData = () => { // 写入到Firebase对应type的路径下,避免不同类型数据互相覆盖 firebase.database() .ref(`/${this.collectionType}`) .set(this.state[this.collectionType]); }; handleSubmit = event => { event.preventDefault(); // 动态取当前对应集合的数据 const collection = this.state[this.collectionType]; // 追加新的媒体数据,保留你原有业务字段即可 collection.push({ // 你原本要存储的字段,比如名称、评分、录入时间等 }); // 动态更新状态 this.setState({ [this.collectionType]: collection }); }; // 其他原有逻辑比如输入事件处理、表单渲染等都可以直接复用,只需把之前写死的movies/books替换成this.collectionType的动态读取即可 render() { // 渲染逻辑和你之前的MovieInput/BookInput保持一致即可 } }
调用方式
完全符合你的预期:
- 电影输入组件:
<MediaInput type='movies'/> - 书籍输入组件:
<MediaInput type='books'/>
内容的提问来源于stack exchange,提问作者Michel
相关产品推荐
相关产品推荐

