2
\$\begingroup\$

To display all the shops, I get data from a database (Firestore) and push them into array and setState, and use map to display shops from this.state{ shops }.

This is working okay, but I am wondering if there are better ways.

export default class Shop extends Component {
  constructor(props) {
    super(props);
    this.state = {
      shops: [],
    };
  }

  async componentDidMount() {
    const querySnapshot = await db.mShopsCollection().get();
    const shops = [];
    querySnapshot.forEach((doc) => {
      const shop = {
        id: doc.id,
        address1: doc.data().address1,
        address2: doc.data().address2,
        address3: doc.data().address3,
        name: doc.data().name,
        prefecture: doc.data().prefecture,
        zip_code: doc.data().zip_code,
      };
      shops.push(shop);
    });
    this.setState({ shops });
  }

  render() {
    const { shops } = this.state;
    return (
      <View>
        {shops.map((shop) => (
          <TouchableOpacity onPress={this.handleShowMap} key={shop.id}>
            <View>
              <View>
                <Text>{shop.name}</Text>
                <Text>
                  〒
                  {shop.zip_code}
                  {'\n'}
                  {shop.prefecture}
                  {shop.address1}
                  {shop.address2}
                  {'\n'}
                  {shop.address3}
                </Text>
            </View>
          </TouchableOpacity>
        ))}
      </View>
    );
  }
}
```
\$\endgroup\$
1
  • 1
    \$\begingroup\$ The current question title of your question is too generic to be helpful. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How do I ask a good question?. \$\endgroup\$ – BCdotWEB May 6 '20 at 10:09
1
\$\begingroup\$

There are a couple of improvements you can make in your componentDidMount.

First, you create an empty array of shops, then push to it in every iteration over the querySnapshot. When constructing an array by transforming another array (or array-like collection), the appropriate method to use is Array.prototype.map. You can get an array of documents from the snapshot by accessing its .docs property.

Second, rather than calling doc.data many times repetitively, you can make an array of properties and extract each of them from the document being iterated over, putting them into a new object with Object.fromEntries:

async componentDidMount() {
  const querySnapshot = await db.mShopsCollection().get();
  const properties = ['address1', 'address2', 'address3', 'name', 'prefecture', 'zip_code'];
  const shops = querySnapshot.docs.map((doc) => {
    const data = doc.data();
    return {
      id: doc.id,
      ...Object.fromEntries(properties.map(prop => data[prop]))
    };
  });
  this.setState({ shops });
}

Lodash's pick is another method that can be used to extract certain properties from an object into a new object.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.