I need to get the component to update data on click

Viewed 60

When the app loads, the sidebar grabs data from the API and populates it as tags.

When you click one of these links tags, it grabs the URL associated with the looped tag, stores that URL in local storage, and then loads the Main Component.

The Main Component should be able to display the section title from the API, that could be a list, detail, or tile.

The problem I'm having is, every time I click a , nothing happens in the main component. So it just grabs the first URL from local storage, and that's it, no matter how many links you click.

So I need to know how to make the main component update? re-mount? re-render? when you click a sidebar link.

the goal is that when you click a link, the URL is different for each of them, and the data they can display is different. So depending on which link you click, the data sent to the main component has to be different to represent that.

Sidebar Component:

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';

export default class Sidebar extends Component {
    constructor(props) {
        super(props);
        this.state = {
            sb_headers: []
        }
    }

    componentWillMount() {
        axios.get('https://btuat-api.azurewebsites.net/api/view')
            .then(response => {
                this.setState({ sb_headers: response.data.menu.menuItems });
                console.log('API Response:', response.data);
            })
    }

    storeUrl = (url) => {
        console.log('Store URL function called:', url);
        localStorage.setItem('menu_url', url);
    }

    render() {

        return (
            <div>
                <div className='navbar my-auto'>
                    <p className='nav-content'></p>
                </div>
                <div className='sidebar-content'>
                    <div className="list-group list-group-flush">
                        {this.state.sb_headers.map((header, index) => (
                            <Link key={index} to='/' className="list-group-item list-group-item-action" aria-current="true" onClick={() => this.storeUrl(header.url)}>
                                <span className='icon-text'>{header.title}</span>
                            </Link>
                        ))}
                    </div>
                </div>
            </div>
        )
    }
}

Main Component:

import React, { Component } from 'react';
import axios from 'axios';

export default class ComponentContainer extends Component {
    constructor(props) {
        super(props);

        this.state = {
            apiData: []

        }
    }

    componentDidMount() {
        axios.get(localStorage.getItem('menu_url'))
            .then(response => {

                response.data.view.sections.map((sections, index) => (
                    console.log('Section Type:', sections.sectionType)
                ))

                this.setState({ 'apiData': response.data.view.sections });
            });
    }

    shouldComponentUpdate() {
        return true
    }

    render() {

        console.log('Axios response to state:', this.state.apiData);

        var loop;

        loop = this.state.apiData.map(function (sections, index) {
            if (sections.sectionType == 'Tile1') {
                return <p key={index}>This is a tile component.</p>;
            }
            else if (sections.sectionType == 'Details') {
                return <p key={index}>This is a details component.</p>;
            } else {
                return <p key={index}>this is a list component.</p>
            }
        })




        return (
            <div>

                {loop}
            </div>
        )
    }
}

function App() {
  return (


    <Router>
      <div className='container-fluid p-0'>
        <div className='row'>
          <div className='d-none d-sm-none d-md-none d-lg-block col-lg-2 sidebar'>
            <Sidebar />
          </div>
          <div className='col-sm-12 col-md-12 col-lg-10 router-container'>
            <Navbar />
            <Route exact path='/' component={ComponentContainer} />
          </div>
        </div>
      </div>
    </Router >

  );
}

export default App;
1 Answers

React will only to listen changes in incoming props or state and you can reliably respond to that changes in the props/state with componentDidUpdate() lifecycle method. As is, your Main component only get values from local state once when the component loads and nothing more. I suggest you make your component receive data in form of props or state and listens to the changes with the appropriate lifecycle method.

Related