简体   繁体   中英

How to clone children in React

I want to write a simple component, that does clone its children and add a marginBottom: 30 to it.

This does work great using <View> as sibling. Unfortunately it does not work using a component as sibling.

CustomListItem component:

// @flow
import * as React from 'react';

type Props = {
  children: React.Node,
};

/**
 *
 */
function CustomListItem ({ children }: Props) {
  return React.Children.map(children, child => {
    const style = [
      child.props.style,
      { marginBottom: 30 },
    ];
    return React.cloneElement(child, { style });
  });
}

export default CustomListItem;

Outcome using the component:

// works
<CustomListItem>
    <Text>This is great.</Text>
</CustomListItem>

// works as well
<CustomListItem>
    <View>
        <CustomComponent></CustomComponent>
    </View>
</CustomListItem>

// does not work. Why?
<CustomListItem>
    <CustomComponent></CustomComponent>
</CustomListItem>

This is the CustomComponent I've been using for testing purposes:

// @flow
import * as React from 'react';
import { View } from 'react-native';

type Props = {
  children: React.Node,
};

function CustomComponent(props: Props) {
  return <View>{props.children}</View>;
}

export default CustomComponent;

It does not matter if I insert a <Text> or <View> element as a child of my <CustomComponent> , so I did not insert this in this example.

That's because your component does not delegate the style prop. In React in general, passing style to a custom component doesn't style it automatically, you have to manually set it up:

type Props = {
  children: React.Node,
  style: object
};

function CustomComponent(props: Props) {
  return <View style={props.style}>{props.children}</View>;
}

This will capture the style property from props and apply it to the wrapping View .


You could use a higher order component, but it would turn out pretty much the same, though you could make it more reusable:

const withStyles = (component, style) => React.cloneElement(component, { style });

Then use it as:

return withStyles(child, style);

Usually HOCs have a reference to the actual component function or class like CustomComponent , not an already created element. But in this case, you don't so they're not that helpful.

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