Initiate Activation Programmatically

Here is a component I am working with:

class LanguageScreen extends Component {

    _onPressButton() {

    }

    render() {
        var enButton = <RoundButton 
            buttonStyle={'black-bordered'}
            text={'EN'}
            locale={'en'}
            selected={true}
            style={styles.roundButtonStyle}
            onPress={this._onPressButton}
        />
        var arButton = <RoundButton
            buttonStyle={'golden-gradient'}
            text={'ع'}
            locale={'ar'}
            selected={false}
            style={styles.roundButtonStyle}
            onPress={this._onPressButton}
        />
        return(
            <View style={styles.rootViewStyle}>
                <View style={styles.buttonContainerRootViewStyle}>
                    <View style={styles.buttonContainerViewStyle}>
                        {enButton}
                        {arButton}
                    </View>
                </View>
                <View style={styles.submitButtonContainerViewStyle}>
                    <Button style={styles.submitButtonStyle}/>
                </View>
            </View>
        );
    }
}

I want the styling of one button to change when the user clicks on another, like in this screenshot here: https://i.sstatic.net/Akeko.png

In other words, I want only one button to be highlighted at a time. If the user clicks on EN, I want it to stay highlighted and remove highlight from the other button.

This is the RoundButton component class I'm using:

class RoundButton extends Component {

    constructor(props) {
        super(props);
        this.state = { isSelected: true === props.selected };
    }

    onClickListen = () => {
        this.setState({
            isSelected: !this.state.isSelected 
        });
        this.forceUpdate();
    }

    render() {
        if (this.state.isSelected) {
            return this.goldenGradient(this.props);
        } else {
            return this.blackBordered(this.props)
        }   
    }

    goldenGradient(props) {
        return(
            <TouchableOpacity
                style={styles.buttonStyle}
                onPress={this.props.onPress}
                onPressOut={this.onClickListen}
            >
                <LinearGradient
                    colors={['#E9E2B0', '#977743']}
                    start={{x: 1.0, y: 0.0}}
                    end={{x: 0.0, y: 1.0}}
                    style={styles.linearGradient}
                >
                    <Text style={this.props.locale == 'ar' ? styles.goldenGradientTextStyleAr : styles.goldenGradientTextStyle}>
                        {props.text}
                    </Text>
                </LinearGradient>
            </TouchableOpacity>
        );
    }

    blackBordered(props) {
        return(
            <TouchableOpacity
                style={
                    styles.buttonStyle,
                    styles.blackBorderedStyle
                }
                onPress={this.props.onPress}
                onPressOut={this.onClickListen}
            >
                <Text style={this.props.locale == 'ar' ? styles.blackBorderedTextStyleAr : styles.blackBorderedTextStyle}>
                    {props.text}
                </Text>
            </TouchableOpacity>
        );
    }
}

I have been trying to make it so that clicking on one button will also trigger a click event for the other button, but I haven't found a solution that works yet. Any suggestions on how I can achieve this?

Answer №1

To efficiently manage button highlights, the father component should be responsible for it. The current selected button should be stored in the state of the father component, and a boolean prop should be passed to indicate if a button is selected or not. It's important to handle the 'selected' prop in the father component rather than within each individual button.

Following this approach ensures that the top-down data flow, which React is built upon, remains uninterrupted.

UPDATE

Father Component

Add constructor:

constructor(props) {
  super(props);

  this.state = {
    selectedButton: 'en'
  };

  this._onPressButton = this._onPressButton.bind(this); 
}

On button press:

_onPressButton(button) {
  this.setState({
    selectedButton: button
  });
}

Buttons initialization:

const arabicButton = <RoundButton
        buttonStyle={'golden-gradient'}
        text={'ع'}
        locale={'ar'}
        selected={this.checkButtonSelect('ar')}
        style={styles.roundButtonStyle}
        onPress={this._onPressButton}/>

const englishButton = <RoundButton 
        buttonStyle={'black-bordered'}
        text={'EN'}
        locale={'en'}
        selected={this.checkButtonSelect('en')}
        style={styles.roundButtonStyle}
        onPress={this._onPressButton}

Check if the button is selected:

checkButtonSelect(button) {
  return this.state.selectedButton === button;
}

Button Component

The implementation is pretty self-explanatory.

class RoundButton extends Component {

constructor(props) {
    super(props);
    this.state = { isSelected: true === props.selected };
}

onClickListen = () => {
    this.props.onPress(this.props.locale);
}

render() {
    if (this.state.isSelected) {
        return this.goldenGradient(this.props);
    } else {
        return this.blackBordered(this.props)
    }   
}

goldenGradient(props) {
    return(
        <TouchableOpacity
            style={styles.buttonStyle}
            onPress={this.onClickListen}
        >
            <LinearGradient
                colors={['#E9E2B0', '#977743']}
                start={{x: 1.0, y: 0.0}}
                end={{x: 0.0, y: 1.0}}
                style={styles.linearGradient}
            >
                <Text style={this.props.locale == 'ar' ? styles.goldenGradientTextStyleAr : styles.goldenGradientTextStyle}>
                    {props.text}
                </Text>
            </LinearGradient>
        </TouchableOpacity>
    );
}

blackBordered(props) {
    return(
        <TouchableOpacity
            style={
                styles.buttonStyle,
                styles.blackBorderedStyle
            }
            onPress={this.props.onPress}
            onPressOut={this.onClickListen}
        >
            <Text style={this.props.locale == 'ar' ? styles.blackBorderedTextStyleAr : styles.blackBorderedTextStyle}>
                {props.text}
            </Text>
        </TouchableOpacity>
    );
}
}

Answer №2

Consider updating the status in the parent component where the buttons are displayed. It might be helpful to keep track of which button was selected in the LanguageScreen and then relay this information to the buttons.

    _handleButtonPress (selectedOption) {
      this.setState({ selectedOption })
    }

    const optionA = <RoundButton 
        onPress={this._handleButtonPress}
        isSelected={this.state.selectedOption === 'option a'}
        ...extraProps
    />
    const optionB = <RoundButton
        onPress={this._handleButtonPress}
        isSelected={this.state.selectedOption === 'option b'}
        ...additionalProps
    />

In your RoundButton component:

handleClick = () => {
    this.props.onPress(this.props.option)
}

render() {
    if (this.props.isSelected) {
        return this.displaySelectedStyle(this.props);
    } else {
        return this.displayDefaultStyle(this.props)
    }   
}

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

What is causing the search feature to malfunction on the Detail page?

In my project, I have different components for handling shows. The Shows.jsx component is responsible for rendering all the shows, while the ProductDetails component displays information about a single show. Additionally, there is a Search component which ...

What is the process of linking this JavaScript code to an outer stylesheet and integrating it with the HTML document?

After encrypting an email address using Hiveware Enkoder, the result can be found below. obfuscated code I typically include it directly inside the div as is. However, I would like to streamline my code by placing it in an external file. While I know ho ...

Contrasting the utilization of Angular $scope dependency with independent usage

As I delve into Angular, there's something that puzzles me. Being a newcomer to Angular, I recall a tutorial where they employed this syntax for applying properties to a controller's scope: app.controller('someCtrl', function(){ ...

Stop jQuery function from activating twice during scrolling

I'm looking for a solution to optimize my code that detects if an element is in the viewport and triggers certain actions. Currently, it re-runs the code every time a scroll event occurs when the element is above the fold. Is there a way to make it on ...

Having trouble with Vue.js array filtering feature in my program

My Vue.js code includes a search input with a dropdown menu populated by an API data array called categories. I am attempting to implement a filter on the search input so that when a value is typed, it filters the dropdown menu items based on the API data. ...

Steps to activate ng-pattern exclusively when the field has been interacted with:

I've encountered a challenge with an input box that has an ng-pattern for link validation. Our project manager has requested that the text 'http://' be pre-filled in the input field, but doing so breaks the ng-pattern validation and prevents ...

Passing Props in Material-UI v5xx with ReactJS: A Beginner's Guide

Struggling with the fact that useStyle() isn't functioning properly in my material-UI v5xx version, I found myself at a loss on how to pass props in this updated edition. In Material-UI v4, it was as simple as: const Navbar = () => { const [open ...

Expo is having trouble locating the module "color-convert" - such a frustrating problem

Having an issue! I ran the command npm start in my terminal and received the following error: Starting project at /home/pc/Documents/Projects/Mobile/weather_app Developer tools running on http://localhost:19002 Cannot find module 'color-convert' ...

Are non-local variables in Node.js considered safe to use?

Would it be secure to implement this code in Node.js/Express.js? // using Object.create(null) to avoid key collisions // refer http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/ var theHash = Object.create(null); exports.store = function (req, ...

Unleash the power of a module by exposing it to the global Window object using the dynamic

In my development process, I am utilizing webpack to bundle and manage my TypeScript modules. However, I am facing a challenge where I need certain modules or chunks to be accessible externally. Can anyone guide me on how to achieve this? Additional conte ...

Having difficulty with the useState hook in a material ui functional component that integrates with Firebase

Currently, I am endeavoring to create a sign-up form utilizing a Material UI functional component. Within this form, I am aiming to trigger a signup event by using the "onClick" attribute attached to the sign-up button. My approach involves passing the ema ...

I'm having trouble getting my object to display using ng-repeat in Angular. Can anyone help me understand what I'm missing?

My goal was to add an object to an array upon clicking an event, which I successfully achieved. However, the objects are not displaying in the ng-repeat as ordered. Can you help me figure out what's missing? angular.module('app', []); an ...

Creating a three-dimensional shape using a transparent image in Three.js

Hey there! I'm currently working on creating a 3D model that features the upper and lower sides as transparent images, while the other sides are a solid color (yellow in this case). var texture = new THREE.TextureLoader().load( 'img.png' ); ...

How can I make an HTML button function with a JavaScript script?

When I click a button in an HTML file, it should trigger a function in a JavaScript file to display an alert that says "hey." However, this simple task is not working for me and I am unsure why. Java Script is enabled in my browser (Google Chrome) and I am ...

Click on ng-click to sort through the blog entries

Currently, I am in the process of developing a blog utilizing AngularJS and JSON. Nearly everything is functioning as expected except for one particular filter item. As I am relatively new to Angular, it presents a bit of a challenge for me. The issue ari ...

Choosing multiple values in the selectize plugin from the controller: A step-by-step guide

Need help with selecting multiple options I'm utilizing the following plugin: https://github.com/selectize/selectize.js/blob/master/docs/usage.md I have an object as displayed in the image below: https://i.stack.imgur.com/sQsKe.png This is my Client ...

The Storybook compilation consistently encounters errors

Check out my repository here: https://github.com/zapify-ui/zapify I'm facing an issue with building Storybook using the command: npm run build-storybook How can I identify the specific error or debug it effectively? The error thrown is: (node:46619) ...

Error in Asp.Net Mvc Bundle: Incorrect Path for Scripts

In my ASP. NET MVC Project, I have set up BundleConfig to include jquery, bootstrap, and modernizr scripts. Everything works well when running locally, with the path leading to the exact .js file. However, when I publish the project to the hosting server, ...

parallax scrolling can be a bit bumpy

While working on a website, I've incorporated a slight parallax effect that is functioning almost perfectly. However, I've noticed that the foreground divs tend to jump a little when scrolling down the page. At the top of the page, there is a di ...

Converting to JSON can be done dynamically by adjusting the format based on the size of an array

Below is the flat array I have: let data = [ ["0000001", "PAUL", "Y", "PELUCHE", "DRAKE", "DOG"], ["0000002", "ECHEBEL", "Y", "CAT", ""], ...