简体   繁体   中英

How to dynamically create and populate an array in React-Native Typescript within a function?

What I have now: As of now in my Storybook file, I create an array and pass it through as a property of my component.

What I am trying to achieve: However, I wish to simply pass length as a prop and then an array gets created dynamically from 1 to length and then display that instead of using an entire object array as a prop. I am not sure how I would do that here.

Here is my setup of my project as I have it now, which is to create an array as a prop, grab the storybook dummy array data, transfer it over and then display it which just seems a mess to me, but all my attempts to dynamically do this result in errors and confusion.

I want orderCount to be a number, then use that number to create a new array of length orderCount and from 1 to orderCount, and then map that. The problem here is I want to do this in displayOrders, but I don't know how to do anything before the .map() in the function.


Storybook:

import {LoyaltyStatus} from '@molecules/LoyaltyStatusCard';
import {storiesOf} from '@storybook/react-native';
import React from 'react';

const dummy = [
  {id: 1},
  {id: 2},
  {id: 3},
  {id: 4},
  {id: 5},
  {id: 6},
  {id: 7},
  {id: 8},
  {id: 9},
];

storiesOf('Loyalty Status', module).add('Default', () => (
  <LoyaltyStatus
    statusTier="Gold"
    points={10}
    orderCount={dummy.map((order) => ({
      orderNumber: order.id,
    }))}
    filled={7}
  />
));


React-native Typescript component:

import * as React from 'react';
import styled from '@styled-components';
import {Text, TextTypes} from '@atoms/Text';
import Icon from 'react-native-vector-icons/FontAwesome5';

export interface ILoyaltyStatusProps {
  orderCount: {
    orderNumber: number;
  }[];
  filled: number;
  statusTier: string;
  points: number;
}

export const LoyaltyStatus: React.FC<ILoyaltyStatusProps> = ({
  orderCount,
  filled,
  statusTier,
  points,
  ...props
}) => {
  const displayOrders = () =>
    orderCount.map((ORDERS) => (
      <OrderTextContainer>
        <OrderText>{ORDERS.orderNumber}</OrderText>
        {ORDERS.orderNumber <= filled && <CrownIcon />}
      </OrderTextContainer>
    ));

  return (
    // eslint-disable-next-line react/jsx-props-no-spreading
    <Container {...props}>
      <InnerContainer>
        <MainContentContainer>
          <TitleText>{`Unlock ${statusTier} Status`}</TitleText>
          <SubText>{`Just order ${orderCount.length} times this month.`}</SubText>
          <OrderContainer>{displayOrders()}</OrderContainer>
        </MainContentContainer>
        <FooterContentContainer>
          <PointsText>
            {`You'll earn ${points} points per dollar when you unlock ${statusTier} Status.`}
          </PointsText>
        </FooterContentContainer>
      </InnerContainer>
      <IconContainer>
        <LockIcon />
      </IconContainer>
    </Container>
  );
};

Edit: My final solution was to do this, but the answers really helped me achieve this. I went with this solution as I thought it made more sense to me and was clearer to read

const populateArray = (length: number) => {
    const newArr = new Array(length);
    for (let i = 1; i <= length; i++) {
      newArr[i] = i;
    }
    return newArr;
  };

  const displayOrders = () =>
    populateArray(orderCount).map((ORDERS) => (
      <OrderTextContainer>
        <OrderText>{ORDERS}</OrderText>
        {ORDERS <= filled && <CrownIcon />}
      </OrderTextContainer>
    ));

You can add getDummyArray function like this:

const getDummyArray = (length) => {
    return length > 0
      ? [...Array(length)].map((_, idx) => ({ id: idx + 1, orderNumber: idx + 1 }))
      : [];
  };

So it becomes like this:

export const LoyaltyStatus: React.FC<ILoyaltyStatusProps> = ({
  orderCount,
  filled,
  statusTier,
  points,
  ...props
}) => {

const getDummyArray = (length) => {
    return length > 0
      ? [...Array(length)].map((_, idx) => ({ id: idx + 1, orderNumber: idx + 1 }))
      : [];
  };

  const displayOrders = () =>
    getDummyArray(orderCount).map((ORDERS) => (
      <OrderTextContainer>
        <OrderText>{ORDERS.orderNumber}</OrderText>
        {ORDERS.orderNumber <= filled && <CrownIcon />}
      </OrderTextContainer>
    ));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM