简体   繁体   中英

TypeScript error in passing props to child component in react

I am building a expense tracker app using react + typescript

expense_type.ts

    export  type IState = {
    id : number,
    text : string,
    amount : number

}

export type IinitialStateType =  {
    transactions : IState[]
}

export type IActions =  {
    type : string,
    payload : any
}

export type contextProps = {
    transactions : IState[];
    addTransaction: (trans: IState) => void;
    deleteTransaction: (id: number) => void;
}

Then I have used API Context and reducer and initialize my initial states in Global State file

GlobalState.tsx

import React , {createContext,useReducer} from 'react'
import {IinitialStateType,contextProps} from '../Types/expense_type'
import AppReducer from './AppReducer'

const initailState : IinitialStateType = {
    transactions : [
          { id: 1, text: 'Flower', amount: -20 },
          { id: 2, text: 'Salary', amount: 300 },
          { id: 3, text: 'Book', amount: -10 },
          { id: 4, text: 'Camera', amount: 150 }
    ]
}

export const GlobalContext = createContext<Partial<contextProps>>({})

export const GlobalProvider : React.FC = ({children}) : JSX.Element => {

    const [state,dispatch] = useReducer(AppReducer,initailState)
    
    return(
        <GlobalContext.Provider value={{
            transactions : state.transactions
        }}>
            {children}
        </GlobalContext.Provider>
    )
}

Then I have used context in TransactionList.tsx component and map all the initial state values and pass those values to child component Transaction.tsx where those values are receiving

TransactionList.tsx

import React ,{useContext}from 'react'
import {GlobalContext} from './../Context/GlobalState'
import {contextProps,IinitialStateType,IState} from '../Types/expense_type'
import {Transaction} from './Transaction'

export const TransactionList : React.FC = () : JSX.Element => {

    const {transactions} : any = useContext(GlobalContext)
    return (
        <>   
            <h3>History</h3>
            <ul className="list">
                { 
                    transactions.map( (transaction : IState , index : number)  => 
                        (<Transaction key={index} transaction={transaction} />
                    )) 
                 }
            </ul>
        
        </>
    )
}

Transaction.tsx

    import React from 'react'
    import {IinitialStateType} from '../Types/expense_type'
    export const Transaction : React.FC<IinitialStateType>= (props : any) : JSX.Element => {

    let sign : string = props.transaction.amount > 0 ? '+' : '-'

    return (
        <>
            <li className={props.transaction.ammount < 0 ? "minus" : "plus"}>
                {props.transaction.text}{" "}
                <span>
                    {sign}${Math.abs(props.transaction.ammount)}
                </span>
                <button
                    className="btn-delete"
                >
                    x
                </button>
            </li>
        </>
    )
}

But while compiling it gives error in TransactionList.tsx file

TypeScript error in C:/Users/Abdul Rehman Aziz/Desktop/New folder/expense-tracker-ts/src/Components/TransactionList.tsx(14,88): Type '{ key: number; transaction: IState; }' is not assignable to type 'IntrinsicAttributes & IState & { children?: ReactNode; }'.   Property 'transaction' does not exist on type 'IntrinsicAttributes & IState & { children?: ReactNode; }'.  TS2322

    12 |             <h3>History</h3>
    13 |             <ul className="list">
  > 14 |                  { transactions.map( transaction => (<Transaction key={transaction.id} transaction={transaction} />)) }
       |                                                                                        ^
    15 |             </ul>
    16 |         </>
    17 |         </>

You have to specify the type of Props for React.FC, not state. Like this:

export const Transaction: React.FC<{ transaction: IState }> = (
  props: any

I have also made a working sample: https://codesandbox.io/s/focused-sanderson-e6zlm?file=/src/App.tsx

Your Transaction component is expecting props of type IinitialStateType and as per your definition of that type it does not has a property called transaction and as well it does not receive one item but an array. If you change the Type of your props in the Transaction component to something like

export const Transaction : React.FC<IState>= (props : any) : JSX.Element => {
...
}

it should help.

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