React: Komponen Singleton React

Dibuat pada 27 Nov 2015  ·  5Komentar  ·  Sumber: facebook/react

Hai teman-teman!
Jadi dalam aplikasi ini saya menulis ada komponen yang disebut "bagian bantuan". Ini pada dasarnya adalah kotak yang menampilkan beberapa teks yang telah ditentukan tentang komponen yang diotak-atik pengguna.

Saya ingin dapat memberi tahu komponen "bagian bantuan" saya komponen mana yang akan diperlihatkan bantuannya. Sampai sekarang, saya menggunakan Flux dengan beberapa tindakan dan penyimpanan. Ini tidak terlalu buruk dan berfungsi dengan baik, namun ini pengaturan yang cukup besar, dengan 2 file yang ditentukan secara khusus untuk tujuan ini. Ada juga sejumlah masalah lain yang saya alami seperti tindakan "bagian bantuan" yang dikirim karena tindakan lain (yang menimbulkan kesalahan "Tidak dapat mengirim di tengah pengiriman").

Namun, jika saya dapat mendefinisikan "bagian bantuan" sebagai tunggal , saya hanya dapat import helpSection from './HelpSection dan selesai dengannya, karena saya akan mendapatkan contoh "bagian bantuan". Yang harus saya lakukan adalah mengekspos metode pada helpSection yang menyetel properti yang ingin saya ubah dan menyebutnya.

Saya tahu itu merusak aliran data searah React, dengan sebuah komponen mengubah komponen lain, tapi mungkin terkadang itu sepadan. Cara saya memikirkannya, ini semacam kombinasi dari toko, beberapa tindakan, dan komponen menjadi satu objek. Banyak komponen hanya akan dibuat satu kali pada waktu proses jadi mungkin ini akan sangat berguna dalam beberapa kasus.

Saya tidak dapat menemukan referensi apa pun untuk ini di web selain di JSfiddle ini , yang tampaknya berfungsi dengan baik (IMO agak tidak jelas). Apakah ini cara yang baik untuk melakukannya?

Saya cukup pemula dalam JavaScript dan React jadi saya mungkin kehilangan beberapa poin yang jelas, semoga tidak.
Apa pendapat Anda tentang ini?
Terima kasih sudah membaca.

(PS Maaf untuk ambiguitas, bahasa Inggris bukan bahasa ibu saya ...: smile :)

Question

Komentar yang paling membantu

Halo @ semua ,

Saya ingin menghidupkan kembali percakapan ini dengan menambahkan sudut pandang lain. Wir bereaksi @ 16 dimungkinkan untuk memasang komponen ke titik-titik tertentu dari DOM dengan menggunakan Portal . Untuk kasus penggunaan ini saya sedang membangun komponen yang berbeda seperti modals atau notifikasi yang harus dirender menjadi komponen tertentu lainnya yang dipasang di App.jsx seperti ini.

App.jsx

[...]
render() {
  return (<SingletonOverlay></SingletonOverlay>)
}
[...]

Notification.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import NotificationComponent from './Notification.js';
import SingletonOverlay from '../general/Overlay.js';

export default class Notification extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      element: null
    };
  }

  componentDidMount() {
    this.setState({ element: ReactDOM.findDOMNode(SingletonOverlay) });
  }

  render() {
    return this.state.element
      ? ReactDOM.createPortal(
        <NotificationComponent>That is a notification</NotificationComponent>,
        this.state.element,
      )
      : null;
  }
}

Pilihan lainnya adalah menemukan domNode dengan document.findElementById atau fungsi serupa dan meneruskannya ke ReactDOM.findDOMNode , yang membuat saya merasa sangat tidak senang karena saya terpaksa meninggalkan "React-Cosmos".

Oleh karena itu saya ingin sekali dapat mencari Instans dari Komponen tertentu yang saya teruskan ke fungsi tersebut, alih-alih meneruskan contoh itu sendiri, untuk fitur yang disebutkan di atas. Saya juga tertarik dengan pendekatan lain tentang cara mengatasi masalah ini.

@jimfb apakah ini layak untuk proposal fitur?

Semua 5 komentar

Ini terlihat seperti pertanyaan penggunaan, bukan bug di inti React. Pertanyaan penggunaan dijawab dengan lebih baik di situs seperti StackOverflow, karena kami mencoba menggunakan masalah github untuk melacak bug di inti React. Karena alasan ini, saya akan menutup masalah ini, tetapi silakan lanjutkan percakapan di sini atau pindahkan ke StackOverflow.

Sehubungan dengan pertanyaan Anda, rekomendasi pribadi saya adalah Anda menghindari lajang.
http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons

Terima kasih balasannya.
Apakah sudah ada cara untuk membuat komponen React sebagai single yang tidak saya sadari? (Saya tidak percaya JSfiddle sampai dievaluasi oleh salah satu dari Anda senior). Jika ada, tolong bagikan dengan saya, karena saya tidak dapat menemukan apa pun tentangnya di dokumen.

Dari halaman dokumen "Berkomunikasi antar komponen" :

Untuk komunikasi antara dua komponen yang tidak memiliki hubungan induk-anak, Anda dapat menyiapkan sistem peristiwa global Anda sendiri.
...
Pola fluks adalah salah satu cara yang memungkinkan untuk mengaturnya.

Seperti yang Anda lihat, lajang tidak disebutkan. Di tautan StackOverflow yang Anda berikan, banyak orang sebenarnya mengatakan bahwa menggunakan lajang berguna dalam beberapa kasus. Dari jawaban kedua:

Lajang memecahkan satu (dan hanya satu) masalah.
Perselisihan Sumber Daya.
Jika Anda memiliki beberapa sumber daya itu
(1) hanya dapat memiliki satu instance, dan
(2) Anda perlu mengelola satu contoh itu,
Anda membutuhkan seorang lajang.

Ini terdengar seperti kasus penggunaan saya (dan beberapa lainnya di dunia React).

Saya yakin ini masih relevan sebagai masalah di GitHub karena sepertinya cara yang relevan untuk menggunakan komponen, dan menurut saya dokumen tersebut harus berisi referensi ke sana.

Instance komponen React memiliki status internal yang diperlukan untuk mengetahui di mana di dalam pohon instance itu berada. Anda tidak dapat merender instance yang sama di banyak tempat. Oleh karena itu, ide contoh tunggal tidak masuk akal di dunia React.

Apa yang ditampilkan di biola itu tidak benar-benar apa yang saya sebut singleton terutama karena argumen contoh tunggal - ini lebih seperti modul dengan statusnya sendiri. Kemudian ketika sebuah instance dirender, ia menggunakan status tertutup (tapi sebenarnya "global"). Ini menipu dan menyimpan referensi ke instance yang dipasang dalam status globalnya dan memaksa pembaruan pada instance yang dipasang. Sekarang tidak ada yang benar-benar menghentikan Anda untuk merender lebih dari ini, yang akan mengakibatkan yang pertama tidak diperbarui. Anda dapat dengan mudah melakukan hal serupa dan mendukung rendering lebih dari 1.

Adapun kami membuat referensi tentang ini di dokumen kami, kami tidak akan melakukannya. Ada banyak pola yang dapat dicapai dengan React, tetapi kami tidak akan membicarakan semuanya.

Terima kasih telah meluangkan waktu untuk menjawab, James.
Pertama, saya benar-benar memahami poin Anda dan menghargai fakta bahwa Anda telah melihat JSfiddle. Izinkan saya membuat pernyataan terakhir.

  1. Apa yang saya maksud sebagai "singleton" adalah contoh dari komponen React yang hanya dirender sekali di seluruh aplikasi. Itulah titik awal saya. Oleh karena itu, masalah yang Anda sebutkan tentang yang pertama tidak diperbarui jika rendering lebih dari 1 tidak begitu relevan.
  2. Saya tahu "mencemari" namespace global tidak disukai, tetapi seperti pendekatan pengkodean apa pun, ia memiliki tempatnya dan penggunaannya. Menggunakan Flux untuk hal semacam ini bermasalah karena berbagai alasan (saya berjuang untuk hari yang baik atau lebih) dan bahkan sekarang solusi yang saya buat tidak begitu baik (Komponen "memilih" antara props atau toko). Menggunakan singleton seperti yang saya jelaskan bisa membuat ini jauh lebih mudah . Saya pikir manfaatnya lebih besar daripada kerugiannya.
  3. Anda tahu, berkenaan dengan dokumen. Saya telah menggunakan React selama sekitar 2 bulan dan bukan rahasia lagi bahwa dokumen sangat kurang di beberapa poin. Bagi saya, belajar menggunakan React itu sulit dan membingungkan.
    Dokumen saat ini berisi 3 kalimat tentang komunikasi antar komponen yang tidak memiliki hubungan "keluarga". Saya memahami variasi pola yang tersedia untuk hal semacam ini jelas bagi Anda, tetapi sejauh ini saya hanya menemukan Flux.
    Pemula sangat bergantung pada docs, dan mungkin daftar pola yang mungkin tersedia untuk memecahkan segala macam masalah adalah hal yang tepat yang harus Anda lakukan. Kita dapat mempelajari pola secara mendalam sendiri, mempelajari alat apa yang tepat untuk tugas itu adalah bagian yang sulit.

Saya ingin mempermudah hal-hal yang sulit bagi saya. Saya pikir itu akan menjadi masalah beberapa baris dan dapat membantu pemula di masa depan.

Saya selalu berakhir dengan menulis komentar besar .. Terima kasih telah bertahan dengan saya dan membaca. :tersenyum:

Halo @ semua ,

Saya ingin menghidupkan kembali percakapan ini dengan menambahkan sudut pandang lain. Wir bereaksi @ 16 dimungkinkan untuk memasang komponen ke titik-titik tertentu dari DOM dengan menggunakan Portal . Untuk kasus penggunaan ini saya sedang membangun komponen yang berbeda seperti modals atau notifikasi yang harus dirender menjadi komponen tertentu lainnya yang dipasang di App.jsx seperti ini.

App.jsx

[...]
render() {
  return (<SingletonOverlay></SingletonOverlay>)
}
[...]

Notification.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import NotificationComponent from './Notification.js';
import SingletonOverlay from '../general/Overlay.js';

export default class Notification extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      element: null
    };
  }

  componentDidMount() {
    this.setState({ element: ReactDOM.findDOMNode(SingletonOverlay) });
  }

  render() {
    return this.state.element
      ? ReactDOM.createPortal(
        <NotificationComponent>That is a notification</NotificationComponent>,
        this.state.element,
      )
      : null;
  }
}

Pilihan lainnya adalah menemukan domNode dengan document.findElementById atau fungsi serupa dan meneruskannya ke ReactDOM.findDOMNode , yang membuat saya merasa sangat tidak senang karena saya terpaksa meninggalkan "React-Cosmos".

Oleh karena itu saya ingin sekali dapat mencari Instans dari Komponen tertentu yang saya teruskan ke fungsi tersebut, alih-alih meneruskan contoh itu sendiri, untuk fitur yang disebutkan di atas. Saya juga tertarik dengan pendekatan lain tentang cara mengatasi masalah ini.

@jimfb apakah ini layak untuk proposal fitur?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat