jmahony
jmahony

Reputation: 166

Add class on focus change using Redux and React

I'm trying to add a class to a div wrapping an input on focus with Redux and React.

My React component looks like this:

import React from 'react'

const Input = ({ value, onChange }) => (
  <div className="">
    <input type="email" onChange={onChange} value={value} />
  </div>
)

export default Input

When a user focuses on the input, I want the class selected to be added to the div. The component is connected using react-redux.

The two ways I've tried so far:

Attempt 1

Add an onFocus listener to the input and dispatch an action that adds the inputs focus state into the inputs state , for example:

{
  value: '',
  focused: true
}

If focused is true, add the class with className={focused ? 'selected' : ''}

My concern with this approach is I could get into issues where multiple inputs have focused: true. So I'd have to manage that myself and look through the whole input state and reset to false before setting focus on a new input.

Atempt 2

Add an onFocus listener to the input and dispatch an action that contains the ID of the focused input and store the ID in the state. This would solve the issue of having to reset all other inputs to false.

My concern with this is I'd have to give every input I wanted this feature on a unique ID (this could possibly use Reacts ID). I'd have to add something like className={ID === focusedID ? 'selected' : '')


I feel like there must be a better way to achieve this. Any help would be appreciated.

Thanks

Upvotes: 4

Views: 13189

Answers (2)

QoP
QoP

Reputation: 28407

You dont even need Redux for that, just store the "selected" state in the component.

Something like this

var InputComp = React.createClass({
  getInitialState: function() {
   return {focus: false}
  },
  onFocus : function(){
        this.setState({focus: true})
  },
  onBlur: function(){
      this.setState({focus: false})
  },
  getClass: function(){
      if(this.state.focus === true)
        return "selected";
      else
        return "";
  },
  render: function() {
    var inputClass = this.getClass();
    return <div className={inputClass}><input onBlur={this.onBlur} onFocus={this.onFocus}/></div>
  }
});

ReactDOM.render(
  <InputComp/>,
  document.getElementById('container')
);

jsfiddle

Upvotes: 8

Lajos Arpad
Lajos Arpad

Reputation: 77053

You need to use the :focus pseudo-selector. You need to add a class to your divs, for instance, focusable. If that is done, you need this CSS rule:

.focusable:focus {
    /* Your rules for selected */
}

Upvotes: -1

Related Questions