Definitelytyped: @types/react Memungkinkan untuk merender string dari komponen fungsional

Dibuat pada 13 Okt 2017  ·  19Komentar  ·  Sumber: DefinitelyTyped/DefinitelyTyped

  • [x] Saya mencoba menggunakan paket @types/react dan mengalami masalah.
  • [x] Saya mencoba menggunakan tsc versi stabil terbaru. https://www.npmjs.com/package/typescript
  • [x] Saya punya pertanyaan yang tidak pantas untuk StackOverflow . (Silakan ajukan pertanyaan yang sesuai di sana).
  • [x] [Sebutkan](https://github.com/blog/821-mention-somebody-they-re-notified) penulisnya (lihat Definitions by: di index.d.ts ) agar mereka dapat menanggapi.

    • Penulis: @johnnyreilly , @bbenezech , ...

Dengan pengetikan saat ini, tidak mungkin membuat komponen stateless yang mengembalikan string, angka, boolean... (baru di React 16)

import React from 'react'

const TestString = () => {
    return 'Test String Component'
}

const Component = () => (
    <div>
        <TestString/>
    </div>
)

Kesalahan yang saya dapatkan:

JSX element type 'string' is not a constructor function for JSX elements.

Masalah pertama adalah bahwa saat ini dalam pengetikan komponen stateless tidak dapat mengembalikan apa pun selain instance dari React.Element . Ini harus diubah menjadi (saya pikir, saya mendasarkannya pada perubahan pada metode render , lihat https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index. d.ts#L422)

interface StatelessComponent<P = {}> {
        (props: P & { children?: ReactNode }, context?: any): ReactElement<any> | Array<ReactElement<any>> | string | number | null;
        propTypes?: ValidationMap<P>;
        contextTypes?: ValidationMap<any>;
        defaultProps?: Partial<P>;
        displayName?: string;
}

Masalah kedua adalah bahwa di belakang layar kompilator akan mengonversi jsx menjadi `React.createElement('Test String Component', null)``

Saya mendapatkan kesalahan kompiler yang mengatakan bahwa ini bukan nilai yang valid. Tampaknya itu harus menjadi salah satu nilai yang ditentukan dalam daftar berikut: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L3465.

Adakah pemikiran tentang bagaimana ini bisa diperbaiki?

Komentar yang paling membantu

Ada berita tentang masalah ini?

Semua 19 komentar

@DovydasNavickas @sandersn @tkrotoff @andy-ms @ddwwcruz @apexskier @devrelm @RyanCavanaugh @richseviora @onigoetz @minestarks @yuit @sboehler @ plantain -00 @p-jackson @ miracle2k @voxmatt @morcerf @janechu @gasparder @dyst5422 @rapilabs @cynecx @newyankeecodeshop

Kita mungkin dapat mendefinisikan komponen stateless dan berbasis kelas sebagai mengembalikan ReactNode sekarang. Saya belum bermigrasi ke v16 ya, jadi itu perlu pengujian.

Sepertinya sudah ada PR terbuka. https://github.com/DefinitelyTyped/DefinitelyTyped/pull/20097

Apakah ini sedang dikerjakan di atm?

Saya mencoba mengubahnya tetapi merusak parser JSX jika tipe yang dikembalikan adalah string boolean atau undefined .

Ada PR TypeScript yang sedang berlangsung tentang itu: https://github.com/Microsoft/TypeScript/pull/20239 (Yah ini tentang array tetapi umumnya bagaimana TS harus tahu apa yang diizinkan dalam komponen JSX)

Keren, terima kasih atas pembaruannya!

Apa yang terbaru tentang ini? Saya melihat TS PR yang disebutkan di atas (https://github.com/Microsoft/TypeScript/pull/20239) sekarang ditutup/dikunci. Saya mengalami hal yang sama hari ini, baru mengenal TypeScript + bereaksi, dan bertanya-tanya mengapa komponen saya tidak dapat mengembalikan string tiba-tiba...

Solusinya adalah mengembalikan sebuah fragmen.

return <>0</>

Ada berita tentang masalah ini?

Halo, ada pembaruan atau petunjuk tentang ini :) ?

Ini pada dasarnya adalah duplikat dari #18912. Setelah Microsoft/TypeScript#21699 diselesaikan, kita harus dapat menggunakan ReactNode sebagai tipe pengembalian yang valid untuk komponen fungsi yang mencakup string dan boolean .

Untuk menggeneralisasi masalah, mengapa ia harus menganggap apa yang sah untuk Bereaksi? Dengan pragma Babel @jsx / @jsxFrag , pendekatan seperti JSX ini dapat bekerja dengan fungsi apa pun. Jadi bukan hanya string yang harus diterima; nilai pengembalian apa pun bisa sah, hanya dibatasi oleh penggunaan khusus. Bereaksi itu penting tetapi itu hanya perpustakaan rendering tertentu.

Ini telah terbuka selama hampir beberapa tahun sekarang, apakah ada solusi?

Tentang pengembalian yang disarankan sebuah fragmen <>StringValue masuk ke sini> - Saya kira saya mengalami kesulitan memahami bagaimana saya mendapatkan nilai string, atau jenis nilai lain apa pun yang bukan merupakan React.Element yang benar-benar digunakan dalam kode saya - misalnya jika Saya memiliki fungsi bernama Howdy yang mengembalikan <>"hello"> dan di dalam componentDidMount yang saya miliki

const whatSays =

bagaimana saya mendapatkan nilai string dari fragmen. Saya tidak melihat cara, rasanya cara apa pun untuk menyiasatinya adalah peretasan yang sangat buruk dan mengingat bahwa api Hooks sering digunakan dengan mengembalikan hanya string atau nilai Elemen Non Bereaksi lainnya - misalnya https://github. com/pankod/react-hooks-screen-type/blob/master/src/index.js
menurut saya bug ini benar-benar membuat api Hooks tidak dapat digunakan, dan dengan demikian membuat TypeScript kurang cocok untuk React.

Ini telah terbuka selama hampir beberapa tahun sekarang, apakah ada solusi?

@bryanrasmussen Lihat https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20544#issuecomment -459665668 untuk pembaruan terakhir.

Masalah ini membuat kami menulis kode React biasa untuk mengatasi batasan yang diberlakukan oleh TypeScript. Satu-satunya cara untuk meredam kesalahan ini dengan cara TypeScript adalah dengan memperkenalkan elemen DOM tambahan dan/atau React.Fragments yang ditambahkan ini (menghasilkan sampah) dan mereka tidak diperlukan.

Ini tidak selalu menjadi masalah karena itu muncul setiap sekarang dan dipicu ketika Anda mengembalikan hal-hal yang valid dari komponen React yang sebenarnya bukan JSX.Element, misalnya, sebuah array.

Saya akan senang dengan anotasi tipe yang masuk akal untuk membantu semuanya, tetapi saya harus menghancurkannya dengan hal-hal yang tidak sempurna seperti lapisan tambahan dan/atau any . Tidak baik.

Membungkus dengan React.Fragment yang tidak perlu memiliki biaya (tidak signifikan) saat runtime.

Mungkinkah ini solusi lain tanpa penalti runtime ?

import React, { ReactElement } from 'react'

const TestString = () => {
  return ('Test String Component' as unknown) as ReactElement
}

const Component = () => (
  <div>
    <TestString />
  </div>
)

export default Component

Membungkus dengan React.Fragment yang tidak perlu memiliki biaya (tidak signifikan) saat runtime.

Ini adalah kompromi. Namun, ingin melihat pengetikan yang lebih baik untuk ini. Juga, tidak signifikan, tergantung pada konteksnya. Beberapa fragmen tidak sakit, banyak dari mereka yang akan menyakiti.

Membungkus dengan React.Fragment yang tidak perlu memiliki biaya (tidak signifikan) saat runtime.

Mungkinkah ini solusi lain tanpa penalti runtime ?

import React, { ReactElement } from 'react'

const TestString = () => {
  return ('Test String Component' as unknown) as ReactElement
}

const Component = () => (
  <div>
    <TestString />
  </div>
)

export default Component

Ya, tapi kemudian saya juga kehilangan tipe yang memeriksa fungsinya. Maksud saya, saya juga dapat menghapus TS dari proyek saya tanpa penalti runtime tetapi kemudian saya tidak memiliki pemeriksaan tipe. Jadi solusi Anda pasti berhasil tetapi hanya merusak tujuan TS. Casting ke "apa yang Anda harapkan" seperti mengatakan "Oke, kalau begitu mari kita buang jeda. Siapa yang butuh ini?". Saat Anda membungkusnya dalam sebuah fragmen, Anda mendapatkan pemeriksaan jenis yang benar!

Jadi, ada berita tentang perbaikan?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat