Передача данных из дочернего компонента в родительский компонент в реагировать родной? - PullRequest
1 голос
/ 08 ноября 2019

Я работаю над функциональностью группы в своем приложении и хочу иметь возможность выбрать нескольких друзей и добавить их вместе при создании группы, например, WhatsApp.

Но я не могу это осуществить. У меня есть родительский компонент (AddMembers) и дочерний компонент (AddMembersComp), которые отображаются в Flatlist родительского компонента. Проблема, с которой я сталкиваюсь, заключается в том, что мой метод createGroup () и массив members и каждый раз, когда в дочернем компоненте нажимается кнопка «Добавить», ассоциированный userId помещается в массив members.

Но что происходитвместо этого создается массив членов для каждого дочернего компонента, и после нажатия кнопки «Добавить» uid перемещается в этот массив, связанный с этим конкретным компонентом.

Я хочу добиться того, чтобыхочу нажать uid при нажатии кнопки добавления на каждом дочернем компоненте в универсальный массив, т.е. связанный со всем списком, а не с конкретным компонентом в списке. А затем, в конечном счете, запустите forEach для отправки массива в базу данных.

Снимок экрана с возникающей проблемой:

enter image description here

Как выМожно видеть, что при нажатии на 1-ую кнопку добавления создается новый массив членов, и пользователь нажимает на uid, но при нажатии на 2-ю кнопку добавления создается другой массив, и пользователь помещается в него, а не в старый. Как я могу это исправить?? Пожалуйста, помогите.

Это мой код:

//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>
    );
  }
}

PS Мне интересно, что решение может быть что-то вроде этого: Каждый раз, когда нажимается кнопка добавления, UID отправляется народительский компонент и помещается в массив универсальных членов. Но как мне это осуществить ??

1 Ответ

1 голос
/ 08 ноября 2019

Вам нужно обработать массив '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>
    );
  }
}
...