首页 > 解决方案 > Why I am getting the Typerror cannot read property map of undefined, despite the my transaction state object is updating dynamically?

问题描述

Updated CodeSandbox link here Map function property undefined

The Add transaction button is not rendering the transaction list in transaction history container This piece of code {transaction && transaction.map(trans).... is rendering the app UI but the Add transaction button is not generating the Transaction component dynamically in transaction history container}

The expense tracker app transaction history is not rendering the list after adding the transaction.

transaction state object in dev tools

 import React from 'react';

const AddTransaction = 
({item,amount,setItem,setAmount,transaction,setTransaction}) 
=> {


const onSubmit = (e) => {
e.preventDefault();
setTransaction([...transaction,
                
    {
        text: item,
        amount: amount,
        id: Math.floor(Math.random()*1000),
    }

    ] );

setItem('');
setAmount('');
}

return (
    <div   className='addtransaction-container'>
  
    <div className='add-trans-header'>

        <h4>Add New Transaction</h4>

    </div>

    <form>

    <div className="form-control">

    <label htmlFor="text">Text</label>

    <input type="text" value={item} 
    onChange={(e) => setItem(e.target.value)} 
    placeholder="Enter text..." />

    </div>

    <div className="form-control">

    <label htmlFor="amount"

    >Amount <br />

    (negative - expense, positive - income)
    
    </label>

    <input type="number" value={amount} 
    onChange={(e) => setAmount(e.target.value)} 
    placeholder="Enter amount..." />

    </div>

    <button type='button' onClick={onSubmit} 
            value='submit'
            className="btn">
            Add transaction
    </button>

    </form>

    </div>
    );
  }

  export default AddTransaction;

The map function is not rendering the Transaction component in TransactionList.js file

  import React from 'react'
  import './App.css';
  import Transaction from './Transaction.js';

  const TransactionList = ({text,transaction,amount}) => {


  return (


  <div className='transactionlist-container'>

    <div className='transactionlist-header-container'>

    <h4>

     Transaction History

    </h4>
    
    </div>

    <ul>
           <li>
    
            { transaction.map(trans => 
            
               <Transaction
                amount={transaction.amount}
                text={transaction.text}
                key={transaction.id} />

            )}
        </li>

        </ul>

    
    
    
      </div>
      )
      }

     export default TransactionList;

My Transaction.js file have a ul list with the input text and amount but the component is not rendering in the app UI.

import React from 'react'

const Transaction = ({transaction,text,amount}) => {
return (
    <div className='transaction'>
        {text}<span>{amount}</span>
    </div>
    )
 }

 export default Transaction;

标签: reactjstypeerrormap-function

解决方案


I have recreated the app, which is working without any issue.

Here is the link to the working demo: StackBlitz

enter image description here

import React, { useState, useEffect } from "react";
import TransactionList from "./TransactionList";
import AddTransaction from "./AddTransaction";

const App = () => {
  const [transaction, setTransaction] = useState([]);

  const handleTransaction = value => {
    setTransaction([...transaction, value]);
  };
  const expenseList = transaction.filter(trans => Number(trans.amount) < 0);
  const expense = expenseList.reduce(
    (acc, curr) => acc + Number(curr.amount),
    0
  );

  const amountList = transaction.filter(trans => Number(trans.amount) > 0);
  const amount = amountList.reduce((acc, curr) => acc + Number(curr.amount), 0);

  useEffect(() => {
    console.log("From app:", transaction);
  }, [transaction]);

  return (
    <div className="transactionlist-container">
      <div>
        <span>income: {JSON.stringify(amount)}</span>{" "}
        <span> total expense: {JSON.stringify(expense)}</span>
        <span> balance: {amount + expense}</span>
      </div>
      <TransactionList transaction={transaction} />
      <AddTransaction
        transaction={transaction}
        handleTransaction={handleTransaction}
      />
    </div>
  );
};

export default App;
import React from "react";
import Transaction from "./Transaction";

const TransactionList = ({ transaction }) => {
  console.log("from tl:", transaction);
  return (
    <div className="transactionlist-container">
      <div className="transactionlist-header-container">
        <h4>Transaction History</h4>
      </div>

      {transaction.map(trans => (
        <Transaction amount={trans.amount} text={trans.text} key={trans.id} />
      ))}
    </div>
  );
};

export default TransactionList;
import React from "react";

const Transaction = ({ text, amount }) => {
  return (
    <div className="transaction">
      {text}
      <span>{amount}</span>
    </div>
  );
};

export default Transaction;
import React,{useState} from "react"
const AddTransaction = 
({handleTransaction}) 
=> {
  const [item,setItem] = useState("")
  const [amount, setAmount] = useState(0)
const onSubmit = (e) => {
e.preventDefault();
handleTransaction(     
    {
        text: item,
        amount: amount,
        id: Math.floor(Math.random()*1000),
    }

   );

setItem('');
setAmount('');
}

return (
     <div
        className="inputBox"
      >
  
    <div className='add-trans-header'>

        <h4>Add New Transaction</h4>

    </div>

    <form>

    <div className="form-control">

    <label htmlFor="text">Text</label>

    <input type="text" value={item} 
    onChange={(e) => setItem(e.target.value)} 
    placeholder="Enter text..." />

    </div>

    <div className="form-control">

    <label htmlFor="amount"

    >Amount <br />

    (negative - expense, positive - income)
    
    </label>

    <input type="number" value={amount} 
    onChange={(e) => setAmount(e.target.value)} 
    placeholder="Enter amount..." />

    </div>

    <button type='button' onClick={onSubmit} 
            value='submit'
            className="btn">
            Add transaction
    </button>

    </form>

    </div>
    );
  }

  export default AddTransaction;

推荐阅读