我正在开发应用程序中的群组功能,希望在创建类似whatsapp的群组时能够选择多个朋友并将其添加到一起。
但是我无法做到这一点。 我有一个父组件(AddMembers)和子组件(AddMembersComp)在父组件的平面列表中呈现。我面临的问题是我的createGroup()方法和一个成员数组,并且每次在子组件中按下“添加”按钮时,关联的userId都会被推送到成员数组。
但是正在发生的是,正在为每个子组件创建一个members数组,并在按下“添加”按钮时将uid推送到与该特定组件关联的那个数组。
我想要实现的是我想在按下每个子组件上的添加按钮时将uid推入通用数组,即与整个列表相关联,而不是与列表中的特定组件相关联。然后最终运行forEach将数组推送到数据库。
正在发生的问题的屏幕截图:
如您所见,在点击第一个添加按钮时,会创建一个新的成员数组,并推入uid,但是在点击第二个添加按钮时,会创建另一个成员数组,并且将uid推入其中,而不是将其推入旧的。 我怎样才能解决这个问题?? 请帮忙。
这是我的代码:
//CHILD COMPONENT - AddMembersComp
class AddMembersComp extends Component {
constructor(props) {
super(props);
this.state = {
docId: '',
addedMembers: [],
};
this.email = this.props.email; //Props passed from the parent
this.username = this.props.username;
this.uid = this.props.uid;
this.name = this.props.name;
this.desc = this.props.desc; //Props passed from the parent
this.members = []; //Pushing uids into this array
}
async addMembers() { //Calling this on pressing the add button
await this.members.push(this.uid);
}
createGroup() {
var docRef = firestore()
.collection('Groups')
.doc();
firestore()
.runTransaction(transaction => {
return transaction.get(docRef).then(doc => {
this.setState({docId: doc.id});
transaction.set(docRef, {
name: this.name,
desc: this.desc,
createdOn: new Date(),
});
});
})
.then(() => {
console.log('this.members: ', this.members);
this.setState({addedMembers: this.members});
console.log('state members: ', this.state.addedMembers);
})
.then(() => {
this.state.addedMembers.forEach(member => {
firestore()
.collection('Groups')
.doc(`${this.state.docId}`)
.collection('Members')
.doc(`${member}`)
.set({
role: 'participant',
joinedOn: new Date(),
});
});
});
}
render() {
return (
<View>
<Text>{this.uid}</Text>
<Button
title="Add"
onPress={() => {
this.addMembers().then(() =>
console.log('State members: ', this.members),
);
}}
/>
</View>
);
}
}
// PARENT COMPONENT - AddMembersScreen
class AddMembersScreen extends Component {
constructor(props) {
super(props);
this.state = {
friends: [],
friendsData: [],
};
this.tempFriends = [];
this.tempFriendsData = [];
console.log('Add Members Screen');
this.name = this.props.navigation.getParam('name');
this.desc = this.props.navigation.getParam('desc');
}
componentDidMount() {
this.fetchFriends()
.then(() =>
this.setState({
friends: this.tempFriends,
}),
)
.then(() => this.fetchEachFriend());
}
async fetchFriends() {
const uid = auth().currentUser.uid;
await firestore()
.collection('Friendships')
.where('uid1', '==', `${uid}`)
.get()
.then(doc => {
if (doc.empty) {
null;
console.log('DOC: ', doc.empty);
} else {
doc.forEach(snap => {
console.log(snap.data().uid2);
this.tempFriends.push(snap.data().uid2);
console.log(this.tempFriends);
});
}
})
.catch(err => console.log('Error DOC1 ', err));
await firestore()
.collection('Friendships')
.where('uid2', '==', `${uid}`)
.get()
.then(doc => {
if (doc.empty) {
null;
console.log('DOC2: ', doc.empty);
} else {
doc.forEach(snap => {
console.log(snap.data().uid1);
this.tempFriends.push(snap.data().uid1);
console.log(this.tempFriends);
});
}
})
.catch(err => console.log('Error DOC2 ', err));
}
fetchEachFriend() { //Fetching each friends data to display
this.state.friends.forEach(uid => {
console.log('UID: ', uid);
firestore()
.collection('Users')
.doc(`${uid}`)
.get()
.then(doc => {
console.log('Friend Data ', doc.data());
this.tempFriendsData.push({
uid: doc.id,
data: doc.data(),
});
})
.then(() => this.setState({friendsData: this.tempFriendsData}))
.catch(err => {
console.log('Error fetchEachFriend(): ', err);
});
});
}
_renderItem = ({item}) => (
<View>
<AddMembersComp
email={item.data.email}
username={item.data.username}
uid={item.uid}
name={this.name}
desc={this.desc}
/>
</View>
);
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<FlatList
data={this.state.friendsData}
keyExtractor={(item, index) => index.toString()}
renderItem={this._renderItem}
/>
</View>
);
}
}
P.S我想知道解决方案可能是这样的: 每次按下添加按钮时,uid都会发送到父组件,并被推入通用成员数组。但是我应该怎么做呢?
答案 0 :(得分:1)
您需要像这样处理父级中的“ addedMembers”数组:
// PARENT COMPONENT - AddMembersScreen
class AddMembersScreen extends Component {
constructor(props) {
super(props);
this.state = {
friends: [],
friendsData: [],
addedMembers: []
};
this.tempFriends = [];
this.tempFriendsData = [];
console.log('Add Members Screen');
this.name = this.props.navigation.getParam('name');
this.desc = this.props.navigation.getParam('desc');
}
componentDidMount() {
this.fetchFriends()
.then(() =>
this.setState({
friends: this.tempFriends,
}),
)
.then(() => this.fetchEachFriend());
}
async fetchFriends() {
const uid = auth().currentUser.uid;
await firestore()
.collection('Friendships')
.where('uid1', '==', `${uid}`)
.get()
.then(doc => {
if (doc.empty) {
null;
console.log('DOC: ', doc.empty);
} else {
doc.forEach(snap => {
console.log(snap.data().uid2);
this.tempFriends.push(snap.data().uid2);
console.log(this.tempFriends);
});
}
})
.catch(err => console.log('Error DOC1 ', err));
await firestore()
.collection('Friendships')
.where('uid2', '==', `${uid}`)
.get()
.then(doc => {
if (doc.empty) {
null;
console.log('DOC2: ', doc.empty);
} else {
doc.forEach(snap => {
console.log(snap.data().uid1);
this.tempFriends.push(snap.data().uid1);
console.log(this.tempFriends);
});
}
})
.catch(err => console.log('Error DOC2 ', err));
}
fetchEachFriend() { //Fetching each friends data to display
this.state.friends.forEach(uid => {
console.log('UID: ', uid);
firestore()
.collection('Users')
.doc(`${uid}`)
.get()
.then(doc => {
console.log('Friend Data ', doc.data());
this.tempFriendsData.push({
uid: doc.id,
data: doc.data(),
});
})
.then(() => this.setState({friendsData: this.tempFriendsData}))
.catch(err => {
console.log('Error fetchEachFriend(): ', err);
});
});
}
handleMemberPress = (intUid) => {
const { addedMembers } = this.state
this.setState({
addedMembers: [...addedMembers, intUid]
})
}
_renderItem = ({item}) => (
<View>
<AddMembersComp
onPress={this.handleMemberPress}
email={item.data.email}
username={item.data.username}
uid={item.uid}
name={this.name}
desc={this.desc}
/>
</View>
);
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<FlatList
data={this.state.friendsData}
keyExtractor={(item, index) => index.toString()}
renderItem={this._renderItem}
/>
</View>
);
}
}
// CHILD COMPONENT - AddMembersComp
class AddMembersComp extends Component {
constructor(props) {
super(props);
this.state = {
docId: '',
addedMembers: [],
};
this.email = this.props.email; //Props passed from the parent
this.username = this.props.username;
this.uid = this.props.uid;
this.name = this.props.name;
this.desc = this.props.desc; //Props passed from the parent
this.members = []; //Pushing uids into this array
}
async addMembers() { //Calling this on pressing the add button
await this.members.push(this.uid);
}
createGroup() {
var docRef = firestore()
.collection('Groups')
.doc();
firestore()
.runTransaction(transaction => {
return transaction.get(docRef).then(doc => {
this.setState({docId: doc.id});
transaction.set(docRef, {
name: this.name,
desc: this.desc,
createdOn: new Date(),
});
});
})
.then(() => {
console.log('this.members: ', this.members);
this.setState({addedMembers: this.members});
console.log('state members: ', this.state.addedMembers);
})
.then(() => {
this.state.addedMembers.forEach(member => {
firestore()
.collection('Groups')
.doc(`${this.state.docId}`)
.collection('Members')
.doc(`${member}`)
.set({
role: 'participant',
joinedOn: new Date(),
});
});
});
}
handleOnPressMember = () => {
const { onPress } = this.props;
onPress(this.uid)
}
render() {
return (
<View>
<Text>{this.uid}</Text>
<Button
title="Add"
onPress={this.handleOnPressMember}
/>
</View>
);
}
}