'what to do when you have multiple repetitive components in react native

So I have the following react native elements component:

<CheckBox
   containerStyle={[styles.checkBox, {borderColor: this.getCheckBoxColor(this.state.art)}]}
   textStyle={[styles.text, {color: this.getCheckBoxColor(this.state.art)}]}
   title='Art'
   checkedColor={this.getCheckBoxColor(this.state.art)}
   uncheckedColor={this.getCheckBoxColor(this.state.art)}
   checkedIcon='paint-brush'
   uncheckedIcon='paint-brush'
   size={15}
   checked={this.state.art}
   onPress={() => this.setState({art: !this.state.art})}
/>

Basically, my app will show a series of checkboxes like this asking the user about different topics they enjoy talking about.

In this case, this checkbox asks the user if they enjoy talking about art. Each topic will therefore have a checkbox and a value in the state (in this case, the value in the state is this.state.art), and the value in state can either be true or false depending on whether the checkbox is checked or not.

The function getCheckBoxColor takes in the state value and sets the color of the checkbox accordingly (if the state is true, the checkbox turns white, if it's false the checkbox turns gray). The thing is, there are 14 different topics and I don't want to copy and paste this component 14 times and have to change the topic in every single one.

I was thinking about maybe having a reusable checkbox component to use as a child component and pass down the topic-specific data it needs as props (like the title, the checked and unchecked icon, and the value in-state) but, since the checkbox needs to alter the state when it is pressed, I'm not sure how to accomplish this because React Native only allows child components to alter the state of the parent component by passing a callback function as a prop to the child, but I don't wanna write 14 different callback functions in my parent component. Is there a better way?



Solution 1:[1]

You could use a generic function in the parent component such as handleCheckboxUpdate = (name) => this.setState({ [name]: !this.state[name] }).

Then, the child element can call it with this.props.onCheckboxUpdate(this.props.title.toLowerCase()).

If the child element's title prop won't always match the key in the parent's state, you could add an additional name prop.

Solution 2:[2]

Define your 14 topics like this.

const topics = [{name: 'art', title: 'Art'}, ...]

Define a common method to render your checkbox.

renderCheckbox(key, title) {
  return (
    <CheckBox
      containerStyle={[styles.checkBox, {borderColor: this.getCheckBoxColor(this.state[key])}]}
      textStyle={[styles.text, {color: this.getCheckBoxColor(this.state[key])}]}
      title=title
      checkedColor={this.getCheckBoxColor(this.state[key])}
      uncheckedColor={this.getCheckBoxColor(this.state[key])}
      checkedIcon='paint-brush'
      uncheckedIcon='paint-brush'
      size={15}
      checked={this.state[key]}
      onPress={() => this.setState({ [key]: !this.state[key] })}
    />
  )
}

Now loop through your topics and render all 14 checkboxes.

renderAllTopics(topics) {
  return(
    {topics.map((row, index) => (
      this.renderCheckbox(row.name, row.title)
    ))}
  )
}

In case you want to use only for specific topics, you can render like this:

this.renderCheckbox(topicName, topicTitle)

Hope this helped.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sean D
Solution 2 Ravi Teja Dandu