Dan Zuzevich
Dan Zuzevich

Reputation: 3831

Creating Multiple Instances Of A Complex React Component

I am currently struggling to come up with an elegant solution for the following feature that needs to be built:

enter image description here

For our purposes, lets call this feature, "Create Program". Create Program needs to have the ability to create multiple instances of what I call a "Program" Component. Not only does it need to do this, but inside each "Program", there is also the ability to create multiple instances of what I will call an "Exercise" Component.

enter image description here

Here are the following pieces of a single Program instance broken down:

- Date Range Picker
- Number Increment/Decrement Input Field
- Day Picker
- Exercise (Multiple instances can be spawned within the Program instance)
  - Everything else inside of exercise is self explanatory...

I have started to conceptualize the data structure I might need in order to attain this. My thought is that some type of Higher Order Component would be utilized to obtain all of the state in some type of object or array. Below, I have created an example in object form, with each key representing a program instance.

// A master object that contains the state for all of the program instances that are currently on the screen
{
  // A single program 
  0: {
    dateStart: ''
    dateEnd: '',
    sessionsPerDay: 0
    daysOfTheWeek: [],
    exercises: [
      // A single exercise
      {

      }
    ]
  },
  1: {
    dateStart: ''
    dateEnd: '',
    sessionsPerDay: 0
    daysOfTheWeek: [],
    exercises: [
      // A single exercise
      {
        ...
      }
    ]
  }
}

I feel like I am struggling with the high level planning of how to do this in a clean, efficient manner. I was hoping to get a well thought out answer from someone explaining how they would approach solving this problem, and what specific features of React they would use to do so. (Higher Order Components, Render Props, Context etc...)

Bonus points if you could detail the component hiearchy you might create for this.

PS. If its not apparent right away, clicking the Add Program button will produce a a brand new Program Component to the screen. Theres currently not a limit to how many can be created.

Upvotes: 2

Views: 3361

Answers (1)

Axnyff
Axnyff

Reputation: 9964

Couldn't something like that work?

class Program extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      exercise: []
    };
    this.createExercise = this.createExercise.bind(this);
  }

  createExercise() {
    const data = this.props.data;
    const newExercises = [...data.exercises, { data: {} }];
    this.props.updateProgram(this.props.index, {
      ...data,
      exercises: newExercises
    });
  }

  render() {
    return (
      <div>
        {JSON.stringify(this.props.data)}
        {this.props.data.exercises.map(exercise => <span>Exercise</span>)}
        <button onClick={this.createExercise}>Create exercise</button>
      </div>
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      programs: []
    };
    this.createProgram = this.createProgram.bind(this);
    this.updateProgram = this.updateProgram.bind(this);
  }

  createProgram() {
    const programs = [
      ...this.state.programs,
      { data: { exercises: [] }, key: Math.random() }
    ];
    this.setState({ programs });
  }

  updateProgram(key, newData) {
    const programs = this.state.programs.map(program => {
      if (key === program.key) {
        return { key, data: newData };
      }
      return program;
    });
    this.setState({ programs });
  }

  render() {
    return (
      <div>
        Programs:
        {this.state.programs.map(program => (
          <Program
            index={program.key}
            key={program.key}
            data={program.data}
            updateProgram={this.updateProgram}
          />
        ))}
        <button onClick={this.createProgram}>Create program</button>
      </div>
    );
  }
}

You don't need anything fancy. If it gets out of hand, then you could use a state management solution to improve it but other than that, I don't see a use for anything fancy

Upvotes: 2

Related Questions