重用React组件来处理不同的DB集合



我有一个关于React的初学者问题。我刚刚写了这个组件:

class MovieInput extends React.Component {
constructor(props) {
super(props);
firebase.initializeApp(config);

this.state = {
movies: []
};
}
....
}

它工作得很好,在Firebase中将数据保存在一个名为movies的集合下。我开始工作的第二个组件看起来像这样:

class BookInput extends React.Component {
constructor(props) {
super(props);
firebase.initializeApp(config);

this.state = {
books: []
};
}
....
}

我已经可以看到,这两个组件的大部分代码将是相同的,使得编写两次没有意义。问题来了。我如何编写一个标准的组件,使用我可以传递的道具,并有这样的东西:

<MediaInput type='movies'/>
<MediaInput type='books'/>

代替:

<MovieInput />
<BookInput />

新组件可能看起来像:

class MediaInput extends React.Component {
constructor(props) {
super(props);
firebase.initializeApp(config);

this.state = {
// Make use of some prop to set collection adequately ....
// This is what I don't know how to do ....
collection: []
};
}
....
}

它可能是有用的设置我的问题的背景,说我受到启发,开始编写上面的代码。

........再做一些工作后:

我正在尝试实现一个更通用的组件(MediaInput)(如srgbnd所建议的答案)。我通过修改MovieInput中的代码来做到这一点(已经工作了)。在它的实现上我仍然遇到一些问题:

componentDidUpdate(prevProps, prevState) {
//if (prevState !== this.state) { // This line may need to be modified to the following.
if (prevState.db !== this.state.db) { 
this.writeUserData();
}
}
writeUserData = () => {
firebase.database()
.ref("/")
.set(this.state);
};

handleSubmit = event => {
event.preventDefault();
.....
// These 3 lines should be modified. Probably replacing movies by something like state.db.{props.type} ???
const { movies } = this.state;
movies.push({ ... });
this.setState({ movies });
.....
};

我不熟悉firebase数据库。

但是如果我假设

Firebase.database()
.ref("/")
.set(this.state);

自己处理状态的不同键(就像每个值上的所有CRUD行为),这个简单的技巧应该适用于您的typeprops:

class MediaInput extends React.Component {
constructor(props) {
super(props);
firebase.initializeApp(config);

this.state = {
// The array will have the key 'movies' or 'books'
[props.type]: []
};
}
....
}

但是要注意总是定义一个'type' prop !

首先,我将把firebase细节放在一个单独的类中,以尊重SOLID依赖倒置原则。例如:

class AppDatabase {
constructor() {
firebase.initializeApp(config);
}
addCollection(data) {
return firebase.database().ref('/').set(data);
}
}

第二,我会像你一样使用prop类型。

<MediaInput type='movies'/>
<MediaInput type='books'/>
最后,在组件中使用AppDatabase。例如
import { AppDatabase } from '../services';
class MediaInput extends React.Component {
constructor(props) {
super(props);
this.appDatabase = new AppDatabase();

this.state = {
db: {
[props.type]: []
}
};
}
addCollection() {
this.appDatabase.addCollection(this.state.db);
}
}

最新更新