skip to Main Content

I have "My React component" as the following:

'use client';

import styles from './range-slider.module.css'

// range input = track & thumb

export default function RangeSlider({minState, maxState} : 
    {minState: [string, Function], maxState: [string, Function]}) {
  const [min, setMin] = minState;
  const [max, setMax] = maxState;

  const handleMin = (e: React.ChangeEvent<HTMLInputElement>) => {
    setMin(parseInt(e.target.value) < parseInt(max)? e.target.value : max);
  };

  const handleMax = (e: React.ChangeEvent<HTMLInputElement>) => {
    setMax(parseInt(e.target.value) > parseInt(min)? e.target.value : min);
  };

  return (
    <div>
      <div className={styles.rangeInput}>
        <div className={styles.sliderCtrl}>
          <input 
            type="range" 
            className={`${styles.slider} ${styles.min}`} 
            min="0" 
            max="100"
            value = {min}
            onChange={handleMin}/>
          <input 
            type="range" 
            className={`${styles.slider} ${styles.max}`} 
            min="0" 
            max="100"
            value={max}
            onChange={handleMax}/>
        </div>
        <div className={styles.inputCtrl}>
          <div className="min">
            <input 
              className="val-input" 
              type="number" 
              min="0" 
              max="100"
              value={min}
              onChange={handleMin}/>
          </div>
          <div className="max">
            <input 
              className="val-input" 
              type="number" 
              min="0" 
              max="100"
              value={max}
              onChange={handleMax}/>
          </div>
        </div>
      </div>
    </div>
  )
}

However, I suspect it may not be a good practice to pass the useState as a props to the RangeSlider. My question 1 is whether this is good practice and what are the suggest way to do it.

In fact, my primary purpose of mine is just to grab the value of the RangeSlider (i.e. the value of the two range input nested within it) from its parent component, I am grateful if anyone could tell me sth about it, and that’s question 2.

2

Answers


  1. use useRef hook to reference the input element and get what you want.

     import React, { useRef } from 'react';
     import styles from './range-slider.module.css';
        
    export default function RangeSlider({ minState, maxState }) {
      const [min, setMin] = minState;
      const [max, setMax] = maxState;
      
      // Create refs for min and max inputs
      const minInputRef = useRef(null);
      const maxInputRef = useRef(null);
    
      const handleMin = (e) => {
        const value = parseInt(e.target.value);
        setMin(value < parseInt(max) ? value : max);
      };
    
      const handleMax = (e) => {
        const value = parseInt(e.target.value);
        setMax(value > parseInt(min) ? value : min);
      };
    
      return (
        <div>
          <div className={styles.rangeInput}>
            <div className={styles.sliderCtrl}>
              <input 
                type="range" 
                className={`${styles.slider} ${styles.min}`} 
                min="0" 
                max="100"
                value={min}
                onChange={handleMin}
                ref={minInputRef} 
              />
              <input 
                type="range" 
                className={`${styles.slider} ${styles.max}`} 
                min="0" 
                max="100"
                value={max}
                onChange={handleMax}
                ref={maxInputRef} 
              />
            </div>
            <div className={styles.inputCtrl}>
              <div className="min">
                <input 
                  className="val-input" 
                  type="number" 
                  min="0" 
                  max="100"
                  value={min}
                  onChange={handleMin}
                  ref={minInputRef} 
                />
              </div>
              <div className="max">
                <input 
                  className="val-input" 
                  type="number" 
                  min="0" 
                  max="100"
                  value={max}
                  onChange={handleMax}
                  ref={maxInputRef} 
                />
              </div>
            </div>
          </div>
        </div>
      );
    }
    
    Login or Signup to reply.
  2. See my comments, but I’ll write this as an answer.

    You already have the value in the parent component

    Your parent component (by looking at the API of your RangeSlider) must look something along the lines of this:

    const minState = useState(0);
    const maxState = useState(100);
    
    return (
       <RangerSlider minState={minState} maxState={maxState}/>
    )
    

    This means that if you want to "grab" the values in the parent component, due to an event handler for example, you already have them in minState and maxState. Grab them like this:

    const minState = useState(0);
    const maxState = useState(100);
    
    const handleClick = () => {
       const minValueOfRangeSlider = minState[0];
       const maxValueOfRangeSlider = maxState[0];
    
       // do something with them
    }
    
    return (
       <>
        <RangerSlider minState={minState} maxState={maxState}/>
        <button onClick={handleClick}>Submit</button>
       </>
    )
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search