0
votes

I need to implement a kind of Master/Detail View for a Web Application in React. Since the app should be integrated into a CakePHP app I can't use React Router for handling the routes (since CakePHP would process them).

I have a List of Items and want to navigate through them, showing a Detail View. Items are nested, so there're SubItems to navigate to.

Navigation Mockup

For now I got a ItemList Component, showing a list of Cards with a clickhandler. How can I change the View without changing the url?

ItemList Component looks like:

class ItemList extends React.Component {
  constructor(props) {
      super(props);

      this.state = {
          itemList: []
      }
  }

  componentDidMount() {
    fetchItems(...)
  }
    
  render() {
    return(
      <div>
        {this.state.itemList.map(item => (
          <Item key={item.id} item={item} />
        ))}
      </div>
    );
  }
}

Item Component looks like:

class Item extends React.Component {
constructor(props) {
  super(props);

  this.state = {
    item: props.item,
  }
}

handleClick = () => {
  // How to navigate to another Component?
}

render() {
  return(
    <div>
      <div className="card my-2" onClick={this.handleClick}>
        <div className="card-body">
          <h5 className="card-title">{this.state.item.title}</h5>
          <p className="card-text">{this.state.item.description}</p>
        </div>
      </div>
    </div>
  );
 }
}

Thanks in advance!

1
You can e.g. have the current view in state. In the render method you render different things depending on the value of the currentView state value. On click you change the state valueniklas

1 Answers

0
votes

You should have a parent component (let's say MainView) that has a state (let's say selectedItemId).

class MainView extends React.Component {
  constructor(props) {
      super(props);

      this.state = {
          selectedItemId: [null]
      }
  }

  componentDidMount() {
    
  }
    
  render() {
    return(

      {!selectedItemId && (<ItemList />)}
      {selectedItemId && (
         <ItemDetail id={selectedItemId} />
       )}
    );
  }
}

As you can see, it renders different components based on the selectedItemId state value.

Inside the ItemList handleClick you call the setState of the parent MainView to set the selected item ID.

So using conditional rendering inside the render() function of MainView you can render the ItemList when no item is selected and ItemDetail when you have selected one.

I'm not really used to ES6 syntax components so my code can be wrong somewhere, but you can get the message ;)