在 React TS 中将道具传递给孩子时出错

Posted

技术标签:

【中文标题】在 React TS 中将道具传递给孩子时出错【英文标题】:Getting an error while passing props to child in react TS 【发布时间】:2022-01-12 06:04:08 【问题描述】:

我是 React 和 Typescript 的新手。当我尝试将道具从父母传递给孩子时,我收到错误:

TS2322: Type ' changeValue: () => void; ' is not assignable to type 'IntrinsicAttributes &  children?: ReactNode; '.   Property 'changeValue' does not exist on type 'IntrinsicAttributes &  children?: ReactNode; '.

父.tsx:

import * as React from 'react';
import  Child  from '../components/Child';

const Parent: React.FC = () => 

    function changeValue() 
        console.log("hello");
    
  return (
    <div>
        <Child changeValue=changeValue/>
      </div>
  );
;
export default Parent;

Child.tsx:

import * as React from 'react';
import  useState  from 'react';

export const Child: React.FC = (props) => 
  const [textValue, setTextValue] = useState(
    'let name; \n' + 'let age; \n' + 'name = 5;'
  );

  return (
    <div>
      <textarea
        id="details"
        name="details"
        value=props.data
        onChange=() => changeValue
      />
    </div>
  );
;

我在 *** 中看到了一些答案,但无法弄清楚错误出现的原因。我不确定我在这里缺少什么。 提前致谢。

【问题讨论】:

您忘记在子组件中调用带括号的函数:onChange=() =&gt; props.changeValue() 添加后我也收到错误:TS2339:属性'changeValue'不存在类型'孩子?:ReactNode; '。 在继续前进之前最好退后一步:您究竟希望您的 Child 组件做什么(您希望它如何表现)? (同样的问题也适用于父母。)将此目标添加到您的问题中,以便我们知道如何帮助您获得正确的组件类型。 当子文本区域发生一些变化时,我想更新父文本区域中的某些内容。这就是为什么我试图传递一个父方法并将在子的 onChange 上执行。 另一件事,是否可以将父函数传递给子函数并执行子函数的更改? 【参考方案1】:

这是一个在 TypeScript React 中使用 controlled textarea 元素的 lifting state up 的功能示例:

TS Playground link

import 
  default as React,
  ReactElement,
  useState,
 from 'react';

type ChildProps = 
  handleChange: (value: string) => void;
  text: string;
;

const Child = (props: ChildProps): ReactElement => 
  return (
    <div>
      <textarea
        id="details"
        name="details"
        onChange=ev => props.handleChange(ev.target.value)
        value=props.text
      />
    </div>
  );
;

const Parent = (): ReactElement => 
  const [textValue, setTextValue] = useState('let name; \n' + 'let age; \n' + 'name = 5;');

  const handleTextValueChange = (value: string) => 
    console.log(value);
    setTextValue(value);
  ;

  return (
    <div>
      <Child text=textValue handleChange=handleTextValueChange />
    </div>
  );
;

您可以使用这个 sn-p 代码运行上面的示例来查看它是否正常工作:

textarea 
  height: 50vh;
  width: 70vw;
<div id="root"></div><script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script><script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script><script src="https://unpkg.com/@babel/standalone@7.16.4/babel.min.js"></script><script>Babel.registerPreset('tsx', presets: [[Babel.availablePresets['typescript'], allExtensions: true, isTSX: true]]);</script>
<script type="text/babel" data-type="module" data-presets="tsx,react">

/**
 * The following line is here because this Stack Overflow snippet uses the
 * UMD module for React. In your code, you'd use the commented `import` lines
 * below it.
 */
const useState = React;

// import ReactDOM from 'react-dom';
// import 
//   default as React,
//   ReactElement,
//   useState,
//  from 'react';

type ChildProps = 
  handleChange: (value: string) => void;
  text: string;
;

const Child = (props: ChildProps): ReactElement => 
  return (
    <div>
      <textarea
        id="details"
        name="details"
        onChange=ev => props.handleChange(ev.target.value)
        value=props.text
      />
    </div>
  );
;

const Parent = (): ReactElement => 
  const [textValue, setTextValue] = useState('let name; \n' + 'let age; \n' + 'name = 5;');

  const handleTextValueChange = (value: string) => 
    console.log(value);
    setTextValue(value);
  ;

  return (
    <div>
      <Child text=textValue handleChange=handleTextValueChange />
    </div>
  );
;

function Example (): ReactElement 
  return <Parent />;


ReactDOM.render(<Example />, document.getElementById('root'));

</script>

【讨论】:

非常感谢。我错过了添加 ChildProps 属性。它现在正在工作。 @lakshmiravalirimmalapudi 互联网上有很多关于使用React.FC 的(不好的)建议。不要使用它,而是:像普通的 TS 函数一样输入你的 React 函数。如果它们返回 React 元素,请使用 ReactElement 作为返回类型。 好的,但是当我想在父组件中使用子组件的某些功能时,它可以吗? @lakshmiravalirimmalapudi 我不确定我是否理解您的问题。如果您的意思是“按照我在this comment 中描述的方式键入组件是否适用于编译器和您的运行时代码?”那么答案是肯定的。 我的问题是如果 Childs 组件中有一个方法,我想从父组件调用它。有可能吗?

以上是关于在 React TS 中将道具传递给孩子时出错的主要内容,如果未能解决你的问题,请参考以下文章

页面未呈现;在 react-router-dom 中使用受保护的路由将道具传递给孩子时

如何在 React js 中将道具传递给 API URL?

如何在 React 中将不同的道具从父组件传递给多个子组件?

使用 React 钩子,我如何更新通过道具传递给孩子的对象?

通过道具 React 将 WS 连接传递给孩子

我可以通过 props.children React JS 将道具传递给孩子吗