RuntimeError
RuntimeError

Reputation: 1390

NativeBase: render component inside accordion

In my React Native application, I want to implement an Accordion from Native Base. Unfortunately, it seems that it is only possible to add a string as content in dataArray.

Now I would like to render a component with multiselection inside this accordion, not just text. But I am absolutely not able to get this working.

Here is my code.

Accordion.tsx:

imports ...

type Props = {};

interface ArrayContent {
  title: string;
  content: any;
}

export default class Accordion extends Component<Props> {

  // PickerInput is the component that should be rendered inside content of dataArray
  renderPickerInput = () => {
    return <PickerInput></PickerInput>;
  };

  dataArray = [
    {
      title: 'GENERAL',
      content: this.renderPickerInput(), // render component here, but it seems that it takes only string
    },
  ];

  renderHeader(item: ArrayContent, expanded: boolean) {
    return (
      <View>
        <Text>{item.title}</Text>
        {expanded ? (
          <Icon name="arrow-dropup" />
        ) : (
          <Icon name="arrow-dropdown" />
        )}
      </View>
    );
  }
  renderContent(item: ArrayContent) {
    return (
      <Text>
        {item.content}
      </Text>
    );
  }
  render() {
    return (
      <Accordion
        dataArray={this.dataArray}
        renderHeader={this.renderHeader}
        renderContent={this.renderContent}
      />
    );
  }
}

... and the component, PickerInput.tsx:

imports ...

const choices = [
  {
    id: '1',
    name: 'Eric',
  },
  {
    id: '2',
    name: 'Kyle',
  },
  {
    id: '3',
    name: 'Kenny',
  },
  {
    id: '4',
    name: 'Stan',
  },
];

function PickerInput() {
  const [items, setItems] = useState(choices);

  const toggleSelect = item => {
    setItems(
      items.map(element => {
        if (item === element) {
          element.selected = !element.selected;
        }
        return element;
      }),
    );
  };

  const clearSelection = () => {
    setItems(
      items.map(i => {
        i.selected = false;
        return i;
      }),
    );
  };

  const onPress = item => {
    toggleSelect(item);
  };

  const renderItem = item => {
    return (
      <View>
        <ListItem
          onPress={() => onPress(item)}
          key={item.id}>
          <Body>
            <Text>{item.name}</Text>
          </Body>
        </ListItem>
      </View>
    );
  };

  return (
    <Container>
      <List>
        {items.map(item => {
          return renderItem(item);
        })}
      </List>
    </Container>
  );
}

export default PickerInput;

Do you have an idea if this is even possible? If not, what can I do instead of an Accordion to achieve a collapsible component with a Picker inside?

Upvotes: 2

Views: 2546

Answers (1)

aytek
aytek

Reputation: 1942

You wrapped your custom component with Text. Try to remove it.

renderContent(item: ArrayContent) {
   return item.content;
}

Upvotes: 2

Related Questions