27

マーケティング ランディング ページを管理するための CMS システムを構築しています。[ランディング ページの編集] ビューで、ユーザーが編集しているランディング ページに関連付けられているスタイルシートを読み込めるようにしたいと考えています。Reactでこのようなことを行うにはどうすればよいですか?

私のアプリは完全に React であり、同形であり、Koaで実行されています。問題のページの基本的なコンポーネント階層は次のようになります。

App.jsx (has `<head>` tag)
└── Layout.jsx (dictates page structure, sidebars, etc.)
    └── EditLandingPage.jsx (shows the landing page in edit mode)

ランディング ページのデータ (読み込むスタイルシートのパスを含む) は、 で非同期に取得されEditLandingPageますComponentDidMount

追加情報が必要な場合はお知らせください。これを理解してもらいたいです!

おまけ: ページから移動するときにスタイルシートをアンロードしたいと思いますComponentWillUnmount

4

7 に答える 7

35

反応の状態を使用して、動的にロードするスタイルシートのパスを更新するだけです。

import * as React from 'react';

export default class MainPage extends React.Component{
    constructor(props){
        super(props);
        this.state = {stylePath: 'style1.css'};
    }

    handleButtonClick(){
        this.setState({stylePath: 'style2.css'});
    }

    render(){
        return (
            <div>
                <link rel="stylesheet" type="text/css" href={this.state.stylePath} />
                <button type="button" onClick={this.handleButtonClick.bind(this)}>Click to update stylesheet</button>
            </div>
        )
    }
};

また、react コンポーネントとして実装しました。npm install react-dynamic-style-loader でインストールできます。
私のgithubリポジトリをチェックして調べてください:
https://github.com/burakhanalkan/react-dynamic-style-loader

于 2016-01-17T10:15:21.500 に答える
8

これは素数 mixin teritority です。まず、スタイル シートを管理するヘルパーを定義します。

スタイルシートをロードし、その成功の約束を返す関数が必要です。スタイルシートは、負荷を検出するには実際にはかなり狂っています...

function loadStyleSheet(url){
  var sheet = document.createElement('link');
  sheet.rel = 'stylesheet';
  sheet.href = url;
  sheet.type = 'text/css';
  document.head.appendChild(sheet);
  var _timer;

  // TODO: handle failure
  return new Promise(function(resolve){
    sheet.onload = resolve;
    sheet.addEventListener('load', resolve);
    sheet.onreadystatechange = function(){
      if (sheet.readyState === 'loaded' || sheet.readyState === 'complete') {
        resolve();
      }
    };

    _timer = setInterval(function(){
      try {
        for (var i=0; i<document.styleSheets.length; i++) {
          if (document.styleSheets[i].href === sheet.href) resolve();
        } catch(e) { /* the stylesheet wasn't loaded */ }
      }
    }, 250);
  })
  .then(function(){ clearInterval(_timer); return link; });
}

まあ $#!@... オンロードを貼り付けるだけだと思っていましたが、違います。これはテストされていないため、バグがあれば更新してください。いくつかのブログ記事からコンパイルされています。

残りはかなり簡単です。

  • スタイルシートの読み込みを許可する
  • 利用可能になったら状態を更新する (FOUC を防ぐため)
  • コンポーネントのアンマウント時にロードされたスタイルシートをアンロードします
  • すべての非同期の良さを処理する
var mixin = {
  componentWillMount: function(){
    this._stylesheetPromises = [];
  },
  loadStyleSheet: function(name, url){
    this._stylesheetPromises.push(loadStyleSheet(url))
    .then(function(link){
      var update = {};
      update[name] = true;
      this.setState(update);
    }.bind(this));
  },
  componentWillUnmount: function(){
    this._stylesheetPromises.forEach(function(p){
      // we use the promises because unmount before the download finishes is possible
      p.then(function(link){
        // guard against it being otherwise removed
        if (link.parentNode) link.parentNode.removeChild(link);
      });
    });
  }
};

繰り返しますが、テストされていません。問題がある場合は、これを更新してください。

これでコンポーネントができました。

React.createClass({
  getInitialState: function(){
    return {foo: false};
  },
  componentDidMount: function(){
    this.loadStyleSheet('foo', '/css/views/foo.css');
  },
  render: function(){
    if (!this.state.foo) {
      return <div />
    }

    // return conent that depends on styles
  }
});

残りの作業は、スタイル シートを読み込む前に、そのスタイル シートが既に存在するかどうかを確認することだけです。うまくいけば、これで少なくとも正しい道に進むことができます。

于 2015-02-07T19:57:27.887 に答える