Archimedes Trajano
Archimedes Trajano

Reputation: 41220

How do you add a "custom" attribute for children of a React component in TypeScript?

I have a component that generates a TOC and List for the children. The children are just any JSX.Element. So this works...

<SectionScrollList>
  <View key="first"/>
  <View key="second"/>
  <View key="third"/>
</SectionScrollList>

What I would want is to allow the one using SectionScrollList to add a special prop that I would use called shown e.g.

<SectionScrollList>
  <View key="first" shown={true}/>
  <View key="second" shown={false}/>
  <View key="third" shown={true}/>
</SectionScrollList>

but shown is not part of View is there a way around this aside from

<SectionScrollList>
  {shown1 && (<View key="first" />)}
  {shown2 && (<View key="second" />)}
  {shown3 && (<View key="third" />)}
</SectionScrollList>

UPDATE: Just to be specific since I saw the answers... I am not looking for how to do the filter implementation, which I know I can simply do child.props.shown, but I am looking for the TypeScript typing so that it will allow shown to be added ONLY for children of SectionScrollList because I know in Typescript you can simply add shown as an Intrinsic attribute.

Upvotes: 0

Views: 1478

Answers (3)

tobyscript
tobyscript

Reputation: 139

I think the best approach to this is to use the React.Children utility provided by React. See https://reactjs.org/docs/react-api.html#reactchildren for more info.

For example,

const SectionScrollList = ({ children }) => {
  return (
    <div style={{ marginTop: "40px" }}>
      {children &&
        React.Children.map(children, (child) =>
          child.props.shown
            ? React.cloneElement(child, { ...child.props })
            : null
        )}
    </div>
  );
};

See codesandbox link for reference: https://codesandbox.io/s/wonderful-sutherland-x8i8i

EDIT

This does not answer my question on the types

Well, you can create a type declaration file react.d.ts and add the prop you want in the appropriate interface.

An alternative solution is to create a CustomView component that takes all the props of the in-built View and also the shown prop. Then you can use this in all the child components of SectionScrollList.

See this codesandbox for both solutions https://codesandbox.io/s/billowing-sun-u5tp4

NOTE: The sandbox doesn't pick the shown prop in the first solution for obvious reasons but it works in a proper IDE like VSCode.

Upvotes: 2

fragile_frogs
fragile_frogs

Reputation: 431

You could filter the children inside SectionScrollList to only show children where shown === true.

So basically:


function SectionScrollList(props) {
    let children = React.Children
                     .toArray(props.children)
                     .filter(child => child.props.shown === true)
    // do other things
    return children
}

React.Children.toArray

Upvotes: 0

TR3
TR3

Reputation: 387

var props = { requiredProp: "bar" };
<foo {...props} />; // ok
var badProps = {};
<foo {...badProps} />; // error

I believe this is what you are looking for...

https://www.typescriptlang.org/docs/handbook/jsx.html

Upvotes: 0

Related Questions