reactjs 仅在拖动停止后记录HTML输入范围值

hpxqektj  于 2023-03-17  发布在  React
关注(0)|答案(3)|浏览(101)

如何在停止拖动输入范围时才调用该函数?

state={
  range:500
}

changeHandle=(e)=>{
   const range=e.currentTarget.value;
   this.setState({range});
   this.connectToServer(range);  //call this function only when dragging is stopped
}

connectToServer=async(value)=>{
    await axios.............
}

超文本标记语言

<input onChange={this.handleChange} value={this.state.range} type="range" step="500" min="500" max="10000" />
jv2fixgn

jv2fixgn1#

您可能不想用所有无关的中间onChange值来敲击端点,因此基本上需要对输入的onChange处理程序进行去抖动。
下面是我偶尔使用的一个简单的去抖动实用程序:

const debounce = (fn, delay) => {
  let timerId;
  return (...args) => {
    clearTimeout(timerId);
    timerId = setTimeout(() => fn(...args), delay);
  };
};

但任何第三方的一揽子计划,如洛达什,都是可行的。
接下来的步骤很关键,您不希望阻止状态更新,因此希望将状态更新与服务器调用分开。
componentDidUpdate生命周期方法中调用后端的副作用有两个原因。
1.这是对付副作用的正确方法。
1.它可确保您具有最新的this.state.range
代码:

connectToServer = (value) => console.log("Send to server", value);
debouncedConnectToServer = debounce(this.connectToServer, 500);

componentDidUpdate(prevProps, prevState) {
  if (prevState.range !== this.state.range) {
    this.debouncedConnectToServer(this.state.range);
  }
}

handleChange = (e) => {
  const range = e.currentTarget.value;
  this.setState({ range });
};

演示

完整演示代码:

const debounce = (fn, delay) => {
  let timerId;
  return (...args) => {
    clearTimeout(timerId);
    timerId = setTimeout(() => fn(...args), delay);
  };
};

export default class App extends React.Component {
  state = {
    range: 500
  };

  connectToServer = (value) => console.log("Send to server", value);
  debouncedConnectToServer = debounce(this.connectToServer, 500);

  componentDidUpdate(prevProps, prevState) {
    if (prevState.range !== this.state.range) {
      this.debouncedConnectToServer(this.state.range);
    }
  }

  handleChange = (e) => {
    const range = e.currentTarget.value;
    this.setState({ range });
  };

  render() {
    return (
      <label>
        Input
        <input
          onChange={this.handleChange}
          value={this.state.range}
          type="range"
          step="500"
          min="500"
          max="10000"
        />
      </label>
    );
  }
}
qni6mghb

qni6mghb2#

我假设您希望防止一次又一次地命中API,实际上还有另一种解决方案,即使用debounce函数。
TLDR; debounce做的就是把函数调用延迟这个duration,我假设你用的是reactJS,那么可以这样用lodash实现

import debounce from 'lodash/debounce'

export default function App() {
  const debounceFunc = debounce((val) => handleChange(val), 500)

  const handleChange = val => {
    console.log(val)
    // hit API here
  }
  
  return (
    <div className="App">
      <input
        type="range"
        min="0"
        max={100}
        onChange={e => {
          debounceFunc(e.target.value)
        }}
      />
    </div>
  );
}

你可以在codesandbox上用here试试。这是文档
还有另一种使用去抖动的方法,通过创建自定义钩子useDebounce。如果你对此感兴趣,你可以检查它here

bksxznpy

bksxznpy3#

OnMouseUp对我很有效

<input type='range' min="10" max="120" value={range} 
      onChange={({target}) => {
         setRange(target.value)
      }}
      onMouseUp={(e) => {
         console.log(range)
      }}
  />

相关问题