vendredi 18 octobre 2019

React Native complex conditional rendering design pattern

I have a route in my app that can vary significantly based on the state that's passed into it. For example, let's say we have 3 states: state1, state2, and state3. There's some functional components that are rendered in each one of these states (like a header and footer, however their contents can vary). I also have other components that should only be rendered in state1, other components only in state2, etc.

My question is, what would be the best way to set up the conditional rendering in this route to keep the code scalable and maintainable?

Current implementation: Currently, I pass the state into every downstream component and handle my conditional rendering inside each component based on the state given to it, usually with a switch statement. I've begun running into the issue that adding another state or modifying what I want rendered for a certain state becomes a time consuming and messy process.

Option one: The first pattern I've been thinking about would be creating a different view for each state. These state specific views would only include the components that I want rendered for that specific state. I could then wrap all the views in a higher order component that will render the correct view based on the state passed. I feel like this option would be scalable/maintainable, however I think it would also result in a lot of duplicate code. ex:

switch (currentState) {
  case "state1":
    return <State1Component />
  case "state2":
    return <State2Component />
  ...
}

And the State1Component would look something like this:

class State1Component extends Component {
  state = {
    headerText: "lorem ipsum",
    componentText: "..."
    ...
  }

  render() {
    return (
      <View>
        <Header headerText={headerText} />
        ...
      </View>
    )
  }
}

Second option: Another option I thought of would be to create a single, high level object that contains all the information needed for each downstream component at each different state. This object would be contained in the main route. For example,

stateObject = {
  state1: {
    header: {
      renderComponent: true,
      text: "Welcome to state1"
    },
    component1: {
      renderComponent: false,
    },
    ...
  },
  state2: {
  ...
  }
  ...
}

Now, I would be able to easily pull all the information I need based on the state passed in, and I could pass the information down through props. I feel like this option would be good for minimizing duplicate code, however I think the route component would get busy/complicated as a result.

Aucun commentaire:

Enregistrer un commentaire