Modify the class name of the clicked button and another button when a button is clicked in ReactJs

I have a React component that displays two buttons. When the user clicks on the left button, it should change the class of both buttons and render the ListView component. Similarly, when the user clicks on the right button, it should change the class of both buttons and render the MapView component. I have attempted some solutions in the code below. Please provide feedback on what I might be missing and suggestions on how to achieve the desired behavior.

Thank you in advance!

import React, { Component } from 'react';
import { Typography, withStyles, Button} from '@material-ui/core';
import ListView from './listView/ListView';
import MapView from './mapView/mapView';

const styles = {
    boardHeader: {
        display: 'flex'
    },
    boardTitle: {
        flexGrow: 1,
        fontSize: 18,
        fontWeight: 500,
        color: '#ED8E34'
    },
    buttonList: {
        backgroundColor: '#fff',
        borderRadius: 50,
        fontSize: 12,
        minHeight: 10,
        padding: '0px 30px',
        boxShadow: 'none'
    },
    buttonMap: {
        backgroundColor: '#fff',
        borderRadius: 50,
        fontSize: 12,
        minHeight: 10,
        padding: '0px 30px',
        boxShadow: 'none',
        marginLeft: '-10px'
    },
    activeButtonList: {
        backgroundColor: '#fff',
        borderRadius: 50,
        fontSize: 12,
        minHeight: 10,
        padding: '0px 30px',
        zIndex: 1
    },
    activeButtonMap: {
        backgroundColor: '#fff',
        borderRadius: 50,
        fontSize: 12,
        minHeight: 10,
        padding: '0px 30px',
        marginLeft: '-10px'
    },

};

class BoardContent extends Component {

    constructor(props){
        super(props);
        this.state = {
            active: 1,
        }
    }
    onClickList = (e, active) => {
        this.setState({active})
    }
  render() {
      const { classes } = this.props
      const { active } = this.state
    return (
      <div> 
        <div className={classes.boardHeader}>
            <Typography className={classes.boardTitle}>Select the View</Typography>
            <div>
                <Button variant="contained" size="small" className={active === 1 ? classes.activeButtonList : classes.buttonList} onClick={this.onClickList}>LIST VIEW</Button>
                <Button variant="contained" size="small" className={active === 2 ? classes.activeButtonMap : classes.buttonMap} onClick={this.onClickList}>MAP VIEW</Button> 
            </div>
        </div>
        {active === 1 ? <ListView /> : null}
        {active === 2 ? <MapView /> : null}
      </div>
    )
  }
}

export default withStyles(styles)(BoardContent);

Answer №1

To ensure that this.onClickList receives the necessary parameter, you should pass in active. Instead of using onClick={this.onClickList}, consider using

onClick={event => this.onClickList(event, 1)}
for the list view button and
onClick={event => this.onClickList(event, 2)}
for the map view button.

An alternative approach would be to create separate methods for each button.

handleListViewClick = () => setState({ active: 1 })
handleMapViewClick = () => setState({ active: 2 })

This way, your onClick events would look something like this:

... onClick={handleListViewClick} />
... onClick={handleMapViewClick} />

Answer №2

To properly set the value of active in your event handler for the Button component, you must bind both this and the desired value.

You can achieve this by:

onClick={this.onClickList.bind(this, 1)} // for list button
onClick={this.onClickList.bind(this, 2)} // for map button

Alternatively, you can use arrow functions like so:

onClick={(e) => this.onClickList(e, 1)} // for list button
onClick={(e) => this.onClickList(e, 2)} // for map button

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble displaying complete image (ReactJS, CSS)

I am looking to create a visually stunning landing page that covers the entire screen, showcasing a captivating image. However, I have encountered an issue where only a portion of the image is visible due to additional divs being created. Here is what my ...

What is the process for setting up a new router?

When it comes to templates, the vuestic-admin template from https://github.com/epicmaxco/vuestic-admin stands out as the perfect fit for my needs. However, I have a specific requirement to customize it by adding a new page without displaying it in the side ...

When you use the useState object in NextJS, the context object may appear to be empty

I've encountered an issue while trying to pass a context object in NextJS that uses data from a useState hook. Strangely, the state variable and setState functions are undefined when consumed. It's puzzling because substituting a simple variable ...

What is the best way to share specific links on LinkedIn articles?

When the LinkedIn button is clicked, the entire link does not get passed when the image is clicked. However, the Facebook link works perfectly fine. The LinkedIn button used to work before, has anything changed since then? <div align="center"> < ...

Obtain input from request payload in WCF/ADO.NET Data Service

Why are my parameters getting lost when I try to post to an ADO.NET Data Service? This is what my code looks like: [WebInvoke(Method="POST")] public int MyMethod(int foo, string bar) {...} Here's how I'm making the ajax call using prototype.js ...

Error message: Unable to access property 'post' from undefined - Angular 2

Here is the snippet of code in my component file: import { Component, Injectable, Inject, OnInit, OnDestroy, EventEmitter, Output } from '@angular/core'; import { Http, Response, Headers, RequestOptions } from '@angular/http'; import & ...

"Performing a series of getJSON requests with a delay between each call, iterating through an array

Could someone shed light on why my jQuery/JavaScript code runs with an unexpected flurry of ajax calls instead of at a steady 1-per-second rhythm? var i = 0, l = data.length; function geocode() { $.getJSON( 'https://maps.googleapis.com/maps/api ...

Unable to upload multiple files using formidable in Node.js

app.post('/upload', function (req, res) { var form = new formidable.IncomingForm(); form.parse(req, function (err, fields, files) { try{ if (files.file.name != '') { file_newname = dt.MD5(files.file.name ...

Guide to incorporating HTML within React JSX following the completion of a function that yields an HTML tag

I am currently working on a function that is triggered upon submitting a Form. This function dynamically generates a paragraph based on the response received from an Axios POST request. I am facing some difficulty trying to figure out the best way to inje ...

Tips and tricks for replacing tags using the useStyles() function in React leveraging MUI

Is there a way to correctly utilize makeStyles() in React-Router to eliminate the link decoration? I am still seeing the default text underline even after specifying textDecoration: "none" in my Link component. const useStyles = makeStyles((theme) => ...

Importing Vue and Vuex modules from separate files

Recently, I encountered an uncommon issue. I decided to keep my main.js and store.js files separate in a Vue project. In the store.js file, I imported Vuex, set up a new vuex store, and exported it. However, when importing this file into main.js and settin ...

Center position of modal dialog box is not fixed in material-ui as it sets the maxWidth

My challenge is to adjust the max-width of the Dialog component in material-ui. Whenever I set the maximum width, the modal loses its center positioning. To showcase this issue, I've prepared a basic example: //npm install material-ui import React fr ...

Tips for utilizing the /foo-:bar pathway in Nuxt.js?

I am trying to utilize the router /foo-:bar in Nuxt. Do you have any suggestions on how I could make this work? I attempted using pages/foo-_bar.vue but it did not yield the desired results. ...

Having trouble with adding a class on scroll?

My challenge is to extract the header from this website, by adding an additional class when the user scrolls at a position greater than 0. I thought it would be easy, but Java always presents problems for me. Here’s the code I came up with: <!DOCTY ...

Incorporating various language URLs in Next.js using next-i18n-next functionality

Thinking about using the next-i18next internationalization library. Check out next-i18next on GitHub Curious about how to change the language in the path of my URL. For example: /about-us /over-ons -> takes you to the Dutch version of the about us p ...

Getting this error in React Recoil - "Type 'any[]' is not compatible with type 'never[]' parameter"?

Currently, I am working through the React Recoil Todo List tutorial, however, I am encountering some type errors while following along and I am not sure how to resolve them effectively. Below is the code snippet: export const todoListAtom = atom({ key: ...

Tips on how to engage in a spontaneous audio experience

I am currently developing a Discord bot with the intention of having it play a random mp3 file upon joining a voice channel. case"join": message.delete( {timeout: 5000}) const voiceChannel = message.member.voice.channel ...

Attempt to retrieve JSON-formatted data from a repository on Git

As a novice, I am delving into the world of ajax and experimenting with json files. Utilizing JSON formatted data is something I am keen on mastering. However, my request seems to be yielding an empty outcome. An Update: Below is the piece of code I am wor ...

Sending information from popup to primary controller wit the use of AngularJS - (Plunker example provided) with an autocomplete field embedded in the popup

My scenario is a bit unique compared to passing regular data from a modal to the main controller. The input field in my modal has an autocomplete feature. Here is the Plunker I have included for reference: http://plnkr.co/edit/lpcg6pPSbspjkjmpaX1q?p=prev ...

What is causing all the React components to adjust their heights simultaneously instead of just one

I am creating a Trello-inspired application and I have a component that is rendered multiple times. Within this component, there is a button that, when clicked, should reveal an input field along with another button, resembling the design in this image: be ...