4

質問:

反応コンポーネントのメソッドを他の場所に公開するにはどうすればよいですか?

たとえば、React 外の要素から React-Router の this.context.router.push(location) を呼び出したいとします。

おそらく、ウィンドウ オブジェクトに React コンポーネントのメソッドを追加して、任意の汎用 DOM イベント リスナーやコンソールからでも呼び出せるようにすることはできますか?

背景/ユースケース:

React エコシステムではまだ利用できない多くのプラグインと構成を提供するため、React アプリで jQuery DataTables を使用したいと考えています。

既存の React データ テーブル コンポーネント (以下の実装) から始めました。

オリジナルは、たとえば、セル内の他の React コンポーネントをレンダリングできる render 関数を渡すための優れたオプションを提供します。以下では、「製品名」列のセルが React-Router < Link /> コンポーネントとしてレンダリングされます。

    const data =  [
        { 
          product_id: '5001', 
          product_price: '$5', 
          product_name: 'Apple'
         },
         ...
      ];

    const renderUrl =
      (val, row) => {
        return (<Link to={`/product/${row.product_id}`}>{row.product_name}</Link>);
      };

    const columns = [
        { title: 'Product Name', prop: 'product_id', render: renderUrl },
        { title: 'Price', prop: 'product_price' },
      ];

    <DataTable
      className="datatable-container"
      columns={columns}
      initialData={data}
    />

既存のコンポーネントを変更するために行ったことは、React の DOM 差分アルゴリズムからテーブルを非表示にすることです。そうしないと、jQuery DataTables が DOM を変更したときに壊れてしまうからです。

  1. コンポーネントのrender()コードをクラスのカスタム メソッドgetDtMarkup()に移動します (react ライフサイクル外)。
  2. render()はrefidを持つ空の div を出力するようになりました

      render() {
        return (
          <div>
            <div ref="dtContainer" id="dtContainer"></div>
          </div>
        );
      }
    
  3. componentDidMount は ReactDomServer.renderToStaticMarkup を使用して、React コンポーネントを単純な非反応マークアップに変換し、これを render() から #dtContainer div に追加します。最後に、jQuery DataTables はレンダリングされたテーブル html を派手な「jQuery DataTable」として初期化します。

    componentDidMount() {
    
      let table = this.getDTMarkup();
      let dtContainer = this.refs.dtContainer;
      let renderedTable = ReactDOMServer.renderToStaticMarkup(table, dtContainer);
    
      $('#dtContainer').append(renderedTable);
    
      let jqueryTable = $('#dt'); // hard coded in getDTMarkup() for now
    
      // Turn html table into a jQuery DataTable with desired config options
      jqueryTable.DataTable({
        dom: '<"html5buttons"B>lTfgitp',
        buttons: [
          'copy', 'csv', 'excel', 'pdf', 'print'
        ],
        "pagingType": 'numbers',
        "bAutoWidth": false,
        "bDestroy": true,
        "fnDrawCallback": function() {
          console.log('datatables fnDrawCallback');
        }
      });
    }
    

ソースhttps://github.com/alecperkey/react-jquery-datatables/blob/master/src/Table.js#L89-L111

この質問をしている制限は、この静的な非 React マークアップ内で < Link /> などの React コンポーネントを使用できないことです。今のところ < a href=""> を使用していますが、これによりページがリロードされ、速度が遅くなり、ブラウザが白く点滅します。

4

2 に答える 2