Malo Guertin
Malo Guertin

Reputation: 327

ReactJS best practice with complex data structures

I am integrating React into an existing app. This app is data intensive and the data structure is pretty complicated which makes it a bit hard for me to adapt the React patterns, especially statelessness and composition.

Given data like this:

component: {
  options: [optionA, optionB, optionC]
}

options: {
  optionA : {
    name: 'FOO',
    choices: [choiceA, choiceB, choiceC]
  },
  optionB : {
    name: 'BAR',
    choices: [choiceD, choiceE]
  },
  ...
}

choices: {
  choiceA : {
    type: 'typeA',
    choices: [choiceA, choiceB, choiceC],
    name: 'abb'
  },
  choiceB : {
    type: 'typeB',
    name: 'abc'
  },
  ...
}

Since this data is linked by ids I have two possibilities:

  1. Retrieve children data in parent component and pass it to the children.

  2. Pass the ID and children retrieves it's own data.

One implies dynamically retrieving a components props and the other implies having a "god" parent which has all the necessary data for it's children, which one is the better approach?

My other question is if the component that takes a Choice as its props should display differently depending on the type of it's Choice, is the better approach to make a wrapper component like this? :

class Choice extends Component {
  constructor(props){
    super(props);
  }
  
  render(){
    switch(props.choice.type){
       case "typeA":
         return (<TypeAComponent />);
       case "typeB":
         return (<TypeBComponent />);
       default:
          return (..);
    }
  }
}

Or is there a cleaner alternative (I'm a bit allergic to switch cases)...

Upvotes: 3

Views: 4653

Answers (1)

Dan Homola
Dan Homola

Reputation: 4545

Ad your first question:

I would opt for the first solution i.e. retrieving the data in the parent. This will make move to some kind of state management (redux) if you choose so much easier (it will be handled in one place only).

Ad your second question:

You can get rid of the switch using a dictionary:

const choiceRenderers = {
    "typeA": () => <TypeAComponent />,
    "typeB": () => <TypeBComponent />,
    // etc.
};

class Choice extends Component {
    render() {
        const renderer = choiceRenderers[this.props.choice.type];
        return renderer
            ? renderer()
            : <DefaultChoice />;
    }
}

The potential advantage is that this choice—component mapping could be shared across multiple components without replicating it, you can just store it in a module and import it when needed.

Upvotes: 4

Related Questions