简体   繁体   English

将道具传递给 Typescript 中的功能性 React 组件

[英]Passing props to functional React component in Typescript

I'm converting a class-based React app to use React hooks with functional components, but I'm coming across an odd error when I try and pass props down to a child component.我正在将基于类的 React 应用程序转换为将 React 钩子与功能组件一起使用,但是当我尝试将 props 传递给子组件时遇到了一个奇怪的错误。

There are two props I want to pass: critterType and critter .我想传递两个道具: critterTypecritter

critterType is an enum which is declared like this: critterType是一个enum ,声明如下:

export enum critterType {
    bug,
    fish,
}

critter is an ICritter object with the following interface: critter是一个ICritter object,具有以下接口:

export interface ICritter {
    id: number;
    name: string;
    thumbnail: string;
    location: string;
    price: number;
    times: ITimeSpan[];
    northMonths: number[];
    southMonths: number[];
    silhouetteSize?: number;
}

(We don't need to worry about ITimeSpan for now.) (我们现在不需要担心ITimeSpan 。)

The CritterEntry compenent looks like this: CritterEntry如下所示:

function CritterEntry(typeOfCritter: critterType, critter: ICritter) {
    const critterId = critter.id.toString();    

    const state = store.getState();

    let caughtSource: string[] = [];
    let donatedSource: string[] = [];

    switch(typeOfCritter) {
        case critterType.bug: {
            caughtSource = state.caughtCritters.bugs;
            donatedSource = state.donatedCritters.bugs;
            break;
        }
        case critterType.fish: {
            caughtSource = state.caughtCritters.fish;
            donatedSource = state.donatedCritters.fish;
        }
    }

    const caught = caughtSource.indexOf(critterId) > -1;
    const donated = donatedSource.indexOf(critterId) > -1;

    return (
        <li className={'critterEntry'}>
            <ul>
                <li>{critter.name}</li>
                <li>{critter.price} bells</li>
            </ul>
            <ul>
                <li onClick={() => store.dispatch(catchCritter({id: critterId, critterType: typeOfCritter}))}>{caught ? 'Caught' : 'Not caught'}</li>
                <li onClick={() => store.dispatch(donateCritter({id: critterId, critterType: typeOfCritter}))}>{donated ? 'Donated' : 'Not donated'}</li>
            </ul>
        </li>
    );
}

export default CritterEntry;

(Don't worry too much about state here, either; it's enough to know that it has a caught object and a donated object, both of which have two properties: one for bugs and one for fish , each of which is an array of strings.) (这里也不要太担心state ;知道它有一个caughtbugs和一个donated的 object 就足够了,它们都有两个属性,每个属性是一个用于fish的数组:字符串。)

In the parent component, I'm looping through a list of critter s like so:在父组件中,我正在循环遍历critter的列表,如下所示:

allBugs.map((critter:ICritter) => <CritterEntry typeOfCritter={critterType.bug} critter={critter} key={`all_bug_${critter.id}`} />)

The part that's totally stumping me is that the allBugs.map function is throwing an error:完全难倒我的部分是allBugs.map function 抛出错误:

Type '{ typeOfCritter: critterType; critter: ICritter; key: string; }' is not assignable to type '(IntrinsicAttributes & critterType.bug) | (IntrinsicAttributes & critterType.fish)'.
      Type '{ typeOfCritter: critterType; critter: ICritter; key: string; }' is not assignable to type 'critterType.fish'.

From all the documentation I've read, it seems like I should be able to pass the props sown to the CritterEntry component just as I used to in the class-based app, but that doesn't seem to be the case here.从我读过的所有文档来看,似乎我应该能够像以前在基于类的应用程序中那样将播种的道具传递给CritterEntry组件,但这里似乎并非如此。

I'm probably missing something totally obvious here.我可能在这里遗漏了一些非常明显的东西。 Can anyone spot the error?任何人都可以发现错误吗?

The first argument to the component CritterEntry should be an object which will be the props to that component.组件CritterEntry的第一个参数应该是 object,它将作为该组件的道具。 You should annotate the props as one object instead of passing them as separate arguments.您应该将道具注释为一个 object,而不是将它们作为单独的 arguments 传递。

Try this,尝试这个,

interface ICritterEntryProps {
   typeOfCritter: critterType;
   critter: ICritter;
}

function CritterEntry(props: React.PropsWithChildren<ICritterEntryProps>) {
   // access to typeOfcritter and critter by destructuring from props

   const { typeOfCritter, critter } = props;


   // rest of the component logic
}

Also there is a generic type React.FC that can help you when using arrow functions还有一个泛型类型React.FC可以在使用箭头函数时为您提供帮助

interface ICritterEntryProps {
   typeOfCritter: critterType;
   critter: ICritter;
}

const CritterEntry: React.FC<ICritterEntryProps> = ({ typeOfCritter, critter}) => {
   // component logic
}

The second argument to a functional component can be ref object and can be used when using forwardRef but that is not important here.函数组件的第二个参数可以是ref object 并且可以在使用forwardRef时使用,但这在这里并不重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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