0

Currently, I'm making a system that can control home electrical equipment on the web. Backend is ready, I'm trying to implement a function to adjust the brightness of the light with a slider.

enter image description here

I can set brightness_value variable is assigned a number from 0 to 100 when the slider is moved with the code below.

<input type="range" name="speed" min="0" max="100" 
                value={brightness_value} onChange={(e) => setBrightnessValue(e.target.value)}></input>

The problem is that I want to fire the lightOn function at the same time as I move the slider but I don't know what to do. (I'm already using onChange, so can't I use it?)

LightDetail.js

import React, { useState, useEffect, useCallback, onClick} from 'react';
import axios from 'axios';
import ic_light from "../../images/icons/ic_light.png"

const LightDetail = () => {

  const [light, setLight] = useState([]);

  const [brightness_value, setBrightnessValue] = useState();


// set light strength
  const lightOn = async(data) => {
    await axios.post('xxx.com/light/turn_on',
      {
        brightness: brightness_value
      },
      {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${cookies.get('accesstoken')}`
        },
      })
      .then(result => {
        console.log('Turn on!');
        getDevices();
      })
      .catch(err => {
        console.log('Turn on Missed!');
      });
  }

// get light data from backend
const getDevices = async(data) => {
  await axios.get('xxx.com/device_listr',
    {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${cookies.get('accesstoken')}`
      },
    })
    .then(result => {
      console.log(result.data)
      setLight(result.data.attributes.light);  
    })
    .catch(err => {
      console.log(err);
    });
}

useEffect(() => {
  getDevices();
    }, []);


  return (
    <div className="container">
      <div className="row mx-auto text-center">
          <>
            {light.map((item,i) => 
              <div key={i} className="col-12">
                <div className="box h-100">
                <img className="" src={ic_light} />
                <input type="range" name="speed" min="0" max="100" 
                value={brightness_value} onChange={(e) => setBrightnessValue(e.target.value)}></input><br></br>
                <Link to={`/device_list`} className='btn btn-primary col-4'>Back</Link>
                </div>
              </div>
            )}

          </>
      </div>
    </div>
  );
}
export default LightDetail;

2 Answers 2

1

You can define onChange as a custom event handler where you can do whatever.

Example snippet:

const handleSliderChange = (e) => {
  setLightOn(e.target.value)
  setBrightnessValue(e.target.value)
}

...

<input type="range" name="speed" min="0" max="100" 
                value={brightness_value} onChange={handleSliderChange} />

Sign up to request clarification or add additional context in comments.

2 Comments

should pass e.target.value to lightOn, setstate is asynchronous so the brightness_value will be stale
@Calfut thx. I overlooked the value is passed to the setLightOn func. Snippet updated.
-1

You should use the state to drive the view of the view to do

Just add

useEffect(() => {
  lightOn()
}, [brightness_value])

3 Comments

effects should be avoided when possible, here calling in event handler is more efficient
If I understand the question correctly, the lightOn function should be called when the value is changed. However, this will also fire when the component is rendered for the first time. useEffect should be used if some side effect needs to occur after the page is rendered. To optimize this, it's possible to specify that it should only run if some value changed, this is not supposed to be used to emulate event handlers.
@asynts yeh, you are right

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.