Skip to content
Advertisement

Getting undefined props in functional react components

How to pass the {requests} prop to the RequestRow component after executing the setRequests? My understanding is that the requests get initialized as undefined in the beginning and before being set with the asynchronously called object, it gets passed to the RequestRow component as undefined, and the error occurs.

import React, { useState, useEffect } from 'react';
import 'semantic-ui-css/semantic.min.css';
import Layout from '../../../components/Layout';
import { Button } from 'semantic-ui-react';
import { Link } from '../../../routes';
import Campaign from '../../../blockchain/campaign';
import { Table } from 'semantic-ui-react';
import RequestRow from '../../../components/RequestRow';

const RequestsIndex = ({ address }) => {
  const { Header, Row, HeaderCell, Body } = Table;
  const campaign = Campaign(address);
  const [requestCount, setRequestCount] = useState();
  const [requests, setRequests] = useState([]);

  const getRequests = async () => {
    const count = await campaign.methods.getRequestsCount().call();
    setRequestCount(count);
  };

  let r;

  const req = async () => {
    r = await Promise.all(
      Array(parseInt(requestCount))
        .fill()
        .map((_element, index) => {
          return campaign.methods.requests(index).call();
        })
    );
    setRequests(r);
  };

  useEffect(() => {
    getRequests();
    if (requestCount) {
      req();
    }
  }, [requestCount]);

  return (
    <Layout>
      <h3>Requests List.</h3>
      <Link route={`/campaigns/${address}/requests/new`}>
        <a>
          <Button primary>Add Request</Button>
        </a>
      </Link>
      <Table>
        <Header>
          <Row>
            <HeaderCell>ID</HeaderCell>
            <HeaderCell>Description</HeaderCell>
            <HeaderCell>Amount</HeaderCell>
            <HeaderCell>Recipient</HeaderCell>
            <HeaderCell>Approval Count</HeaderCell>
            <HeaderCell>Approve</HeaderCell>
            <HeaderCell>Finalize</HeaderCell>
          </Row>
        </Header>
        <Body>
          <Row>
            <RequestRow requests={requests}></RequestRow>
          </Row>
        </Body>
      </Table>
    </Layout>
  );
};

export async function getServerSideProps(context) {
  const address = context.query.address;
  return {
    props: { address },
  };
}

export default RequestsIndex;

The RequestRow component is shown below. It takes in the {requests} props, which unfortunately is undefined.

const RequestRow = ({ requests }) => {
      return requests.map((request, index) => {
        return (
          <>
            <div>Request!!!</div>
          </>
        );
      });
    };
    
export default RequestRow;

The snapshot of the error is shown below:

enter image description here

Advertisement

Answer

I think React is trying to render your component before your promises resolve. If that’s the case, all you need to do is set a default value (an empty array in your case) for your requests.

const [requests, setRequests] = useState([]);

May the force be with you.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement