我正在尝试制作自己的去抖动输入元素,在这里我可以发送需要的任何输入组件(如textarea和input)并使其去抖动。我制作了一个debounceComponent,看起来像这样:
import { useState, useCallback } from "react";
import debounce from "lodash.debounce";
const useDebounce = (callback, delay) => {
const debouncedFn = useCallback(
debounce((...args) => callback(...args), delay),
[delay] // will recreate if delay changes
);
return debouncedFn;
};
function DebouncedInput(props) {
const [value, setValue] = useState(props.initialValue);
const debouncedSave = useDebounce(
(nextValue) => props.onChange(nextValue),
1000
);
const handleChange = (event) => {
const { value: nextValue } = event.target;
setValue(nextValue);
debouncedSave(nextValue);
};
return props.renderProps({ ...props, handleChange, value });
//return <textarea value={value} onChange={handleChange} rows={5} cols={50} />;
}
export default DebouncedInput;
这就是我的用法:
<DebouncedInput
initialValue={value}
onChange={handleChange}
rows={5}
cols={50}
renderProps={(props) => <TextArea {...props} />}
/>
但是,如果我像这样使用它,则会出现错误:
对象作为React子对象无效(找到:带有键的对象 {dispatchConfig,_targetInst,_dispatchListeners,_dispatchInstances, nativeEvent,类型,目标,currentTarget,eventPhase,气泡, 可取消,时间戳,默认阻止,被信任, isDefaultPrevented,isPropagationStopped})。如果您打算渲染一个 子集,请改用数组。
您可以看到here的密码和框。 我在这里做错什么,该如何解决?
答案 0 :(得分:1)
在您的DebouncedInput
组件中,更改return语句。
来自
return props.renderProps({ ...props, handleChange, value });
到
return props.renderProps({ ...props, onChange: handleChange, value });
import { useState, useCallback } from "react";
import debounce from "lodash.debounce";
const useDebounce = (callback, delay) => {
const debouncedFn = useCallback(
debounce((...args) => callback(...args), delay),
[delay] // will recreate if delay changes
);
return debouncedFn;
};
function DebouncedInput(props) {
const [value, setValue] = useState(props.initialValue);
const debouncedSave = useDebounce(
(nextValue) => props.onChange(nextValue),
1000
);
const handleChange = (event) => {
const { value: nextValue } = event.target;
setValue(nextValue);
debouncedSave(nextValue);
};
return props.renderProps({ ...props, onChange: handleChange, value });
}
export default DebouncedInput;
此外,不要将所有道具传播到组件,而仅传递与输入元素相关的道具。因此,在这种情况下,调用props.renderProps({ ...props, onChange: handleChange, value })
组件时,DebouncedInput
组件接收的所有道具都直接传递到input
或TextArea
组件,这意味着renderProps
是也被通过了。但通常input
或TextArea
可能没有initialValue
,renderProps
作为道具,这会引发警告。
有多种方法可以避免收到此类警告,以下是其中一种方法
DebouncedInput
,并将输入组件的道具传播为rest
参数function DebouncedInput({initialValue, renderProps, onChange, ...rest}) {
const [value, setValue] = useState(initialValue);
const debouncedSave = useDebounce(
(nextValue) => onChange(nextValue),
1000
);
const handleChange = (event) => {
const { value: nextValue } = event.target;
setValue(nextValue);
debouncedSave(nextValue);
};
return renderProps({ ...rest, onChange: handleChange, value });
}
inputProps
中,并通过renderProps
传递。<DebouncedInput
initialValue={value}
onChange={handleChange}
renderProps={(props) => <TextArea {...props} />}
inputProps={{rows:5, cols:50}}
/>
function DebouncedInput(props) {
const [value, setValue] = useState(props.initialValue);
const debouncedSave = useDebounce(
(nextValue) => props.onChange(nextValue),
1000
);
const handleChange = (event) => {
const { value: nextValue } = event.target;
setValue(nextValue);
debouncedSave(nextValue);
};
return props.renderProps({ ...props.inputProps, onChange: handleChange, value });
}
props
和component
,因此可以像下面这样简单地进行操作 <DebouncedInput
initialValue={value}
onChange={handleChange}
renderProps={(props) => <TextArea {...props} rows={5} cols={50}/>}
/>
function DebouncedInput(props) {
const [value, setValue] = useState(props.initialValue);
const debouncedSave = useDebounce(
(nextValue) => props.onChange(nextValue),
1000
);
const handleChange = (event) => {
const { value: nextValue } = event.target;
setValue(nextValue);
debouncedSave(nextValue);
};
return props.renderProps({ onChange: handleChange, value });
}