Làm thế nào để sử dụng phần tử con với React Stateless Function Component trong TypeScript?


84

Sử dụng TypeScript với React, chúng tôi không còn phải mở rộng React.Propsđể trình biên dịch biết rằng tất cả các đạo cụ thành phần phản ứng có thể có con:

interface MyProps { }

class MyComponent extends React.Component<MyProps, {}> {
  public render(): JSX.Element {
    return <div>{this.props.children}</div>;
  }
}

Tuy nhiên, có vẻ như không phải vậy đối với các thành phần chức năng không trạng thái:

const MyStatelessComponent = (props: MyProps) => {
  return (
    <div>{props.children}</div>
  );
};

Phát ra lỗi biên dịch:

Lỗi: (102, 17) TS2339: Thuộc tính 'con' không tồn tại trên loại 'MyProps'.

Tôi đoán điều này là do thực sự không có cách nào để trình biên dịch biết rằng một hàm vani sẽ được đưa ra childrentrong đối số đạo cụ.

Vì vậy, câu hỏi đặt ra là chúng ta nên sử dụng con như thế nào trong một thành phần chức năng không trạng thái trong TypeScript?

Tôi có thể quay lại cách cũ MyProps extends React.Props, nhưng Propsgiao diện được đánh dấu là không được dùng nữa và các thành phần không trạng thái không có hoặc hỗ trợ Props.refnhư tôi hiểu.

Vì vậy, tôi có thể xác định chỗ dựa childrentheo cách thủ công:

interface MyProps {
  children?: React.ReactNode;
}

Đầu tiên: có ReactNodeđúng loại không?

Thứ hai: Tôi phải viết con là tùy chọn ( ?), nếu không người tiêu dùng sẽ nghĩ rằng đó childrenđược cho là thuộc tính của thành phần ( <MyStatelessComponent children={} />) và gây ra lỗi nếu không được cung cấp giá trị.

Có vẻ như tôi đang thiếu một cái gì đó. Có ai có thể cung cấp một số thông tin rõ ràng về việc liệu ví dụ cuối cùng của tôi có phải là cách sử dụng các thành phần chức năng không trạng thái với trẻ em trong React không?

Câu trả lời:


82

Cập nhật React 16.8: Kể từ React 16.8, các tên React.SFCReact.StatelessComponentkhông được dùng nữa. Trên thực tế, chúng đã trở thành bí danh cho React.FunctionComponentloại hoặc React.FCviết tắt.

Tuy nhiên, bạn sẽ sử dụng chúng theo cùng một cách:

const MyStatelessComponent : React.FunctionComponent<MyProps> = props =>
    <div>
        <p>{props.propInMyProps}</p>
        <p>{props.children}</p>
    </div>

Trước React 16.8 (Cũ hơn):

Hiện tại, bạn có thể sử dụng React.StatelessComponent<>loại, như:

const MyStatelessComponent : React.StatelessComponent<{}> = props =>
    <div>{props.children}</div>

Những gì tôi đã thêm ở đó là thiết lập kiểu trả về của thành phần để React.StatelessComponentnhập.

Đối với một thành phần có đạo cụ tùy chỉnh của riêng bạn (như MyPropsgiao diện):

const MyStatelessComponent : React.StatelessComponent<MyProps> = props =>
    <div>
        <p>{props.propInMyProps}</p>
        <p>{props.children}</p>
    </div>

Bây giờ, propsđã có childrentài sản cũng như những người từ MyPropsgiao diện.

Tôi đã kiểm tra điều này trong phiên bản sắp chữ 2.0.7

Ngoài ra, bạn có thể sử dụng React.SFCthay thế React.StatelessComponentcho ngắn gọn.


Cảm ơn! Dường như tôi đang trên một phiên bản cũ của typings mà không hỗ trợ này ... Tôi đoán đó là thời gian để cắn đạn và sử dụng TS 2.0 với@types
Aaron Beall

2
React.StatelessComponent/ React.SFCkhông được dùng nữa. Nó được khuyến khích để tham khảo React.FunctionComponentthay thế.
Alexander Kachkaev

Lưu ý rằng phương pháp này không có tác dụng nếu bạn có một thành phần chung
FunkeyFlo

92

Bạn có thể sử dụng React.PropsWithChildren<P>loại cho đạo cụ của mình:

interface MyProps { }

function MyComponent(props: React.PropsWithChildren<MyProps>) {
  return <div>{props.children}</div>;
}

0

Bạn có thể dùng

interface YourProps { }
const yourComponent: React.SFC<YourProps> = props => {}

0

Câu trả lời đơn giản hơn: Sử dụng ReactNode:

interface MyProps {
  children?: React.ReactNode
}

Nếu childrenlà tùy chọn hoặc không (nghĩa là có ?hoặc không) phụ thuộc vào thành phần của bạn. Đây ?là cách ngắn gọn nhất để diễn đạt điều đó, vì vậy không có gì sai với điều đó.

Về lịch sử: Đây không nhất thiết là câu trả lời chính xác khi được hỏi ban đầu: Loại ReactNodeđã được thêm vào (gần như) ở dạng hiện tại của nó vào tháng 3 năm 2017 chỉ bởi yêu cầu kéo này , nhưng hầu như tất cả mọi người đọc nó ngày nay đều phải sử dụng phiên bản React đủ hiện đại .

Cuối cùng, về việc chuyển childrendưới dạng "thuộc tính" (trong ngôn ngữ React, sẽ chuyển nó dưới dạng "prop", không phải thuộc tính): Có thể, nhưng trong hầu hết các trường hợp, đọc tốt hơn khi chuyển JSX con:

<MyComponent>
  <p>This is part of the children.</p>
</MyComponent>

đọc dễ dàng hơn

<MyComponent children={<p>This is part of the children.</p>} />
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.