渲染道具组件引发对象作为React子元素无效

时间:2020-10-20 17:17:10

标签: reactjs

我正在尝试制作自己的去抖动输入元素,在这里我可以发送需要的任何输入组件(如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的密码和框。 我在这里做错什么,该如何解决?

1 个答案:

答案 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组件接收的所有道具都直接传递到inputTextArea组件,这意味着renderProps是也被通过了。但通常inputTextArea可能没有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 });

}
  • 将所有与输入/ TextArea相关的道具传递到另一个对象内,如下所示。在这里,我将所有要发送的相关道具作为输入组件的一部分传递给我,它们包装在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 });

}
  • 由于您也从同一位置传递了propscomponent,因此可以像下面这样简单地进行操作
 <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 });

}