Aventadorrre
Aventadorrre

Reputation: 79

How to rewrite setState from class component to useState in functional component?

I want to use this color picker in my React project https://casesandberg.github.io/react-color/#about

Here is example from docs

import React from 'react';
import { SketchPicker } from 'react-color';

class Component extends React.Component {
  state = {
    background: '#fff',
  };

  handleChangeComplete = (color) => {
    this.setState({ background: color.hex });
  };

  render() {
    return (
      <SketchPicker
        color={ this.state.background }
        onChangeComplete={ this.handleChangeComplete }
      />
    );
  }
}

But it's class component. I have functional with useState in my project. One of them is

const [projectColor, setProjectColor] = useState("#F9A8D4");

with default picked color. How to rewrite this class example to use with usestate? I don't get it...

onChangeComplete={ this.handleChangeComplete }

is like setState? And from where is this color variable?

handleChangeComplete = (color) => {
    this.setState({ background: color.hex });
  };

Here is my full code (i don't know what pass to the setProjectColor). Colors is array with colors to pick, and color is default selected color.

const [projectColor, setProjectColor] = useState("#F9A8D4");
  const colors = [
    "#FECACA",
    "#F9A8D4",
    "#FDE68A",
    "#A7F3D0",
    "#BFDBFE",
    "#E5E7EB",
  ];

  const colorPicker = () => {
    return (
      <div className="p-4">
        <CirclePicker
          colors={colors}
          color={projectColor}
          onChangeComplete={(e) => setProjectColor(projectColor)}
        />
      </div>
    );
  };

Upvotes: 0

Views: 783

Answers (3)

Serasb
Serasb

Reputation: 1

You can rewrite the class as the code below

import React, { useCallback, useState } from 'react';
import { SketchPicker } from 'react-color';

function FComponent() {
    const [background, setBackground] = useState('#fff');

    const handleChangeComplete = useCallback((color) => {
        setBackground(color.hex);
    }, []);

    return (
        <SketchPicker
            color={background}
            onChangeComplete={handleChangeComplete}
        />
    );
}

Some explanation to the differences from React.Component and React.FunctionalComponent:

  • React.Components are instantiated as an object. The object are mutable and when you call a method, you will always see all its attributes up to date (when you have access to component's this, you can always see the current props and state objects). The state is managed internally and you can update it with this.setState function.
  • React.FunctionalComponents are simply functions. All the variables and functions declared inside it belong to its scope (very important when we use hooks inside a FC). The state is managed externally to the function scope, using useState hook, that provides mutability through each renders. To be compliant to React behavior (new property to component triggers its rerendering) it is necessary do not declare functions inside the FC component but use the useCallback hook instead, cause each render means new function and maybe a useless rerendering of sub components. See also https://reactjs.org/docs/hooks-reference.html

Upvotes: 0

user8082655
user8082655

Reputation:

You can rewrite your function:

 handleChangeComplete = (color) => {
    this.setState({ background: color.hex });
  };

into:

const handleChangeComplete = React.useCallback((color) => setProjectColor(color), []);

Upvotes: 0

Dennis Vash
Dennis Vash

Reputation: 53894

You only need to use the color object of onChangeComplete callback:

onChangeComplete={(color) => setProjectColor(color.hex)

Full example:

const [projectColor, setProjectColor] = useState("#F9A8D4");

return (
  <div className="p-4">
    <CirclePicker
      colors={colors}
      color={projectColor}
      onChangeComplete={(color) => setProjectColor(color.hex)}
    />
  </div>
);

Upvotes: 2

Related Questions