Don Smythe
Don Smythe

Reputation: 9804

Select and change a specific element in ReactJS

I am trying to toggle the colours of two buttons in ReactJS. I can set the active state property of the selected button OK, but I can't work out how to change the style of another button (calcY) based on my selection (of calcX).

The code is brittle but I am pretty new to react and any pointers on best practices would be appreciated. PS also I am using react-bootstrap for the Form and buttons.

const MyForm = React.createClass({

    handleChange(event, attribute) {
        let eventValue = event.target.value;
        if (attribute === 'calcX'){
            this.setState({active: true});
            this.setState({bsStyle: 'info'});
            let calcXBtn = ReactDOM.findDOMNode(this.refs.calcBtnGroup.refs.calcX);
            calcXBtn.setState({bsStyle: 'default'});
        }
        ...
    }

render() {
    return (
            <Form onSubmit={this.handleSubmit} horizontal>
                <FormGroup>
                    <ButtonGroup ref="calcBtnGroup">
                        <Button active className='btn btn-info'  ref="calcX" onClick={(event) => this.handleChange(event, 'calcX')}>Calculate X</Button>
                        <Button className='btn btn-default' ref="calcY" onClick={(event) => this.handleChange(event, 'calcY')}>Calculate Y</Button>
                    </ButtonGroup>
            ...

        );
    }
});

module.exports = MyForm;

Upvotes: 0

Views: 852

Answers (1)

Sam Pakvis
Sam Pakvis

Reputation: 189

You can set the className or style based of an element (or subcomponent) on the state of your component. It's nice to use a ternary operator and ES6 template literals here.

<Button ref="calcX" className=`btn ${this.state.active ? 'btn-info' : 'btn-default'}` onClick={(event) => this.handleChange(event, 'calcX')}>Calculate X</Button>

What this does, is setting a className based on the state of your component. The <Button> component always has a btn className. If state.active is true, the class btn-info will be added. Otherwise btn-default will be added.

So the only thing you have to do now, is set the state in your handleChange method and the classNames will be rendered appropriately.

Edit: it's not really necessary to use refs here. It's almost never necessary to use refs. You want use React events (onChange, onSubmit, etc.) to set input values on the state, and render those values in the value in your inputs. These are called controlled components. You can read more about it in the official documentation: https://facebook.github.io/react/docs/forms.html

Upvotes: 1

Related Questions