繁体   English   中英

渲染道具组件抛出对象作为 React 子组件无效

[英]Render props component throws Objects are not valid as a React child

我正在尝试制作我自己的去抖动输入元素,我可以在其中发送我需要的任何输入组件,例如 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、type、target、currentTarget、eventPhase、bubbles、cancelable、timeStamp、defaultPrevented、isTrusted、isDefaultPrevented、isPropagationStopped} 的对象)。 如果您打算渲染一组子项,请改用数组。

你可以在这里看到它的代码和框。 我在这里做错了什么,我该如何解决?

在您的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 传播到组件,而是只传递与 input 元素相关的 props。 因此,在这种情况下,当调用props.renderProps({ ...props, onChange: handleChange, value })所有这一切由接收的道具DebouncedInput构件直接传递到inputTextArea该装置部件renderProps也被传递。 但在一般情况下inputTextArea可能没有initialValuerenderProps作为道具,这会引发警告。

有多种方法可以避免收到此类警告,以下是其中一种方法

  • 将所需的 props 传播到DebouncedInput并将输入组件的 props 作为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 });

}
  • 将所有与 input/TextArea 相关的道具传递到另一个对象中,如下所示。 在这里,我传递了我想作为输入组件的一部分发送的所有相关道具,我将其包装在inputProps并通过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 });

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM