簡體   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