Search code examples
javascriptreactjsonclickonfocus

Using onFocus/onClick to trigger a function within an input field in React


OK so I have an input field that whose value is pre-loaded when the component mounts (this.state.color) and I'm attempting to add a handleColorPicker() function either onClick or onFocus that will dropdown a color picker from https://casesandberg.github.io/react-color/. I'll paste the relevant code below:

import React, { Component } from 'react';
import { ChromePicker } from 'react-color';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
       color: 'FFFFFF',
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleColorPicker = this.handleColorPicker.bind(this);
  }

  handleChange(event) {
    this.setState({[event.target.name]: event.target.value});
  }

  handleColorPicker(){
    console.log('open');
    return( 
      <ChromePicker />
    )
  }

  render() {
    return(
      <input
        className="App-textForm"
        type="text"
        name="color"
        value={this.state.color}
        onChange={this.handleChange}
        onClick={this.handleColorPicker}
      />
    );
  }
}

As constructed, it console.logs 'open' every time I click on it.

Is there anything obvious I'm missing as to why that onClick wouldn't trigger the ChromePicker? I've tried changing onClick to onFocus and have tried wrapping my input in a div with an onClick={this.handleColorPicker}. Any help would be appreciated, thanks!


Solution

  • The problem is that you are not rendering the picker, you are just returning it and then doing nothing with it.

    What you need to do is render the picker, you can do that by using the state and hide/show the picker based on the user selection. For example:

    state = {
      showPicker: false,
    };
    
    handleColorPicker(){
      console.log('open');
      this.setState(current => ({
        showPicker: !current.showPicker, // <-- Toggle the state
      }));
    }
    
    render() {
      const { showPicker } = this.state;
    
      return (
        <div>
        <input
          className="App-textForm"
          type="text"
          name="color"
          value={this.state.color}
          onChange={this.handleChange}
          onFocus={this.handleColorPicker} // <--- Open the picker on focus
          onBlur={this.handleColorPicker}  // <--- Hide it on blur? You need to define when to hide it
         />
         { showPicker && <ChromePicker /> }
       </div>
     );
    }
    

    using onFocus and onBlur the state change and the picker gets renderer or not, based on the value of showPicker.

    You need to define when to hide it, onBlur might not be what you want.