React useState-setValue重新渲染组件,即使值相同

时间:2019-02-20 14:16:48

标签: reactjs react-hooks

我在自定义钩子中使用useState钩子。

我正在调用setValue返回的useState函数两次:

1)在onChange事件之后

2)在服务器通知组件更改之后。

事件流是:

  • onChange事件(在组件中)触发setValue = 渲染
  • 我正在使用useEffect =重现后)挂钩来更新更改的服务器-调用了API函数来更新服务器
  • 我有一个自定义服务,可以接收服务器的响应并通知组件
  • 收到通知后,组件再次调用setValue,但在这种情况下,该值相同,因此无需重新呈现。

我的问题是,即使收到的值相同,组件也将在收到更改通知后重新呈现。

我的代码:

增益分量

import * as React from 'react';
import { useDSPParamUpdate } from '../../../Hooks/useDSPParamUpdate';
import { ControlParamProps } from '../..';

const Gain = (props: ControlParamProps) => {

  let min: number = 0;
  let max: number = 0;


  const { paramId, controlId } = props;
  const { param, value, setValue } = useDSPParamUpdate({ controlId, paramId })

  if (param && param.range && param.range.length >= 2) {
    min = param.range[0];
    max = param.range[1];
  }

  /*calls the setValue from the hook*/
  const handleChange = (event: any) => {
    const newValue = event.target.value;
    setValue(newValue);
  }


  return (
    <div className="gain">
      {max}
      <input className="dsp-action range-vertical" type="range"
        min={min}
        max={max}
        value={value}
        onChange={handleChange} />
      {min}
    </div>
  );
}

export default Gain;

useDSPParamUpdate-自定义挂钩

    import * as React from 'react';
        import { ControlParamProps } from '../dsp';
        import { dspService } from '../../core/services/dsp.service';

        export function useDSPParamUpdate(props: ControlParamProps) {

            const initValue = ...
            const [value, setValue] = React.useState(initValue);

            function updateDevice() {
                // calls some API func to update the server (sends the value)
            }

            // subscribes to server changes
            React.useEffect(() => {
                    // subscribrs to server notifications
                    let unsubscribe = dspService.subscribe((newVal) => setValue(newVal));
                return () => {
                    unsubscribe();
                };
            }, []);


            // sends data to the server after update
            React.useEffect(() => {
                updateDevice();
            }, [value]);

            return { param, value, setValue };
        }

1 个答案:

答案 0 :(得分:1)

通常,如果render()被称为加班时间就没问题。

但是如果您愿意,可以通过检查值是否相同来保护调用setValue()

let unsubscribe = dspService.subscribe(
    (newVal) => 
        newVal !== value && setValue(newVal)
);  

也许有点冗长,但与componentDidUpdate

中通常使用的方法相同

请注意,useState没有像shouldComponentUpdate那样提供任何逻辑。因此,如果要以更具声明性的方式进行创建,则必须将组件重构为PureComponent的基于类的访问器。