reactjs - `props.children` nasıl bir JSX öğesine dönüştürülür?
React fonksiyonel bileşenleri ile çocukları şöyle render edebiliriz:
import React from 'react';
const MyComponent = (props: React.PropsWithChildren) => {
return props.children;
}
Ancak, bunu kullanmaya çalıştığımda bir hata alıyorum:
...
return <MyComponent />;
...
veya
...
return (
<MyComponent>
<div>hello</div>
</MyComponent>
);
...
yol açar
'MyComponent' cannot be used as a JSX component. Its return type 'ReactNode' is not a valid JSX element. Type 'undefined' is not assignable to type 'Element | null'.
Bir çözüm, fonksiyonel bileşenin dönüş değerini bir fragment içinde sarmalamaktır:
const MyComponent = (props: React.PropsWithChildren) => {
return <>{props.children}</>; // <= useless fragment is here
}
Ancak, sonra eslint: react/jsx-no-useless-fragment hatasını tetikliyorum.
Çocukları öyle bir şekilde kullanmanın bir yolu var mı ki bu sorunların ikisini de yaşamak zorunda kalmayayım?
Düzenle
İşte bir oyun alanı bağlantısı
Bir parçacık kullanmaktan başka bir şekilde bir ReactNode'u geçerli bir JSX bileşenine dönüştürmenin bir yolu var mı?
Ek Not: eslint-plugin-react, bu kullanım durumu için allowExpressions seçeneğine sahiptir. Temelde, fragment bir ReactNode => JSX öğesi dönüştürme işlemini yaparken "gereksiz" fragment'lara izin verecektir.
Cevap #1
"Faydasız" parça aslında çağırmakla aynı şeydir
React.createElement(React.Fragment, null, props.children);
React.createElement, bir bileşen türünü (React.Fragment) ve alt öğeleri kullanarak o türde ve bu alt öğelere sahip bir JSX öğesi oluşturabilir.
Yani çözüm bunu yapmak:
const MyComponent = (props: React.PropsWithChildren) => {
return React.createElement(React.Fragment, null, props.children);
}
Bu, TS ve eslint'i her ikisini de memnun eder. Ancak, JSX createElement'den daha çok tercih edilir. eslint kuralı için {"allowExpressions": true} seçeneğini etkinleştirmek (daha fazla ayrıntı için soruya bakın) ve JSX tarzı bir parça kullanmak burada en iyi seçenektir.
Herkese yardım için teşekkürler.
Cevap #2
Burada gördüğüm 2 önemli nokta var:
Son kod bloğunuzda çocukların bir fragment içinde sarıldığı revizyon, Typescript'te önemlidir. Children, geçerli bir öğe olmayan bir öğeler dizisi olabilir, bu nedenle bu durumu kapsamak için geçerli bir öğe içinde sarılması gerekir (veya bir dizi olmadığından emin olmak için kontrol edilmelidir). (En azından Typescript ve React'te v16'dan önce.)
Başvurduğunuz ve ikinci hatayı tetikleyen eslint kuralı, fragment içinde sadece bir öğe olduğu için tetikleniyor. Ancak, Typescript tanımına uymak istediğimiz şey bu olduğundan, bu sorun teşkil ediyor. Bu özel durumda, bu hatayı susturmanızı tavsiye ederim.
Bir seçenek, dönüş satırının öncesine bu şekilde bir devre dışı bırakma yorumu eklemektir:
// eslint-disable-next-line react/jsx-no-useless-fragment
return <>{props.children}</>;
