【问题标题】:ReactJS + Flux: How to pass data attribute from HTML?ReactJS + Flux:如何从 HTML 传递数据属性?
【发布时间】:2016-07-10 05:06:45
【问题描述】:

我正在使用 ReactJS(Flux) 和 Laravel 框架。我需要将一个变量从刀片模板传递给 React 组件。我正在尝试使用 data-x 属性。

我的问题是……

  1. 如何在 React(或 Flux 架构)中获取数据?

  2. 您是否有将数据存储在 Flux 中的最佳做法。 app.js 是最好的地方吗?

谢谢,

index.blade.php

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>ReactJS</title>
  </head>
  <body>
    <section id="react" data-domain="{{env("DOMAIN")}}"></section>
    <script src="{{ elixir('js/bundle.js') }}"></script>
  </body>
</html>

/app.js

var React = require('react');
var SampleApp = require('./components/SampleApp.react');

React.render(
  <SampleApp />,
  document.getElementById('react')
);

/components/SampleApp.react

var React = require('react');
var SampleApp = React.createClass({
  render: function() {
    return (
      <div>
        Hello
      </div>
    );
  }
});
module.exports = SampleApp;

================================================ ====

编辑 1

我可以使用 {this.props.domain} 传递数据。下一步是如何以 Flux 方式存储数据。

/app.js

var React = require('react');
var SampleApp = require('./components/SampleApp.react');

var react = document.getElementById('react');

React.render(
  <SampleApp domain={react.dataset.domain}/>,
  react
);

/components/SampleApp.react

var React = require('react');
var SampleApp = React.createClass({
  render: function() {
    return (
      <div>
        Hello {this.props.domain}
      </div>
    );
  }
});
module.exports = SampleApp;

================================================ ====

编辑 2

固定

/index.blade.php
/app.js
/components/SampleApp.react.js
/actions/SampleActionCreators.js
/constans/SampleConstants.js
/dispatcher/SampleAppDispatcher.js
/stores/SampleStore.js

index.blade.php

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>ReactJS</title>
  </head>
  <body>
    <section id="react" data-domain="test.example.com"></section>
    <script src="{{ elixir('js/bundle.js') }}"></script>
  </body>
</html>

/app.js

var React = require('react');
var SampleApp = require('./components/SampleApp.react');

React.render(
  <SampleApp />,
  document.getElementById('react')
);

/components/SampleApp.react.js

var React = require('react');
var SampleActionCreators = require('../actions/SampleActionCreators');
var SampleStore = require('../stores/SampleStore');

function getSampleState() {
  return {
    domain: SampleStore.getDomain()
  };
}

var SampleApp = React.createClass({
  getInitialState: function() {
    return getSampleState();
  },

  componentDidMount: function() {
    SampleStore.addChangeListener(this._onChange);

    var domain = document.querySelector('#react').dataset.domain;
    SampleActionCreators.initData(domain);
  },

  componentWillUnmount: function() {
    SampleStore.removeChangeListener(this._onChange);
  },

  render: function() {
    return (
      <div>
        Hello {this.state.domain}
      </div>
    );
  },

  _onChange: function() {
    this.setState(getSampleState());
  }

});
module.exports = SampleApp;

/actions/SampleActionCreators.js

var SampleAppDispatcher = require('../dispatcher/SampleAppDispatcher');
var SampleConstants = require('../constants/SampleConstants');

var ActionTypes = SampleConstants.ActionTypes;

module.exports = {

    initData: function(domain) {
        SampleAppDispatcher.dispatch({
            type: ActionTypes.SAMPLE_INIT_DATA,
            domain: domain
        });
    },

};

/constans/SampleConstants.js

var keyMirror = require('keymirror');

module.exports = keyMirror({
  ActionTypes: keyMirror({
    SAMPLE_INIT_DATA: null
  })
});

/dispatcher/SampleAppDispatcher.js

var Dispatcher = require('flux').Dispatcher;

module.exports = new Dispatcher();

/stores/SampleStore.js

var SampleAppDispatcher = require('../dispatcher/SampleAppDispatcher');
var SampleConstants = require('../constants/SampleConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');

var CHANGE_EVENT = "change";

var _domain = "";

var SampleStore = assign({}, EventEmitter.prototype, {

    getDomain: function() {
        return _domain;
    },

    emitChange: function() {
        this.emit(CHANGE_EVENT);
    },

    addChangeListener: function(callback) {
        this.on(CHANGE_EVENT, callback);
    },

    removeChangeListener: function(callback) {
        this.removeListener(CHANGE_EVENT, callback);
    }
});

SampleAppDispatcher.register(function(action) {

    switch (action.actionType) {
        case SampleConstants.SAMPLE_INIT_DATA:
            _domain = action.domain;
            SampleStore.emitChange();
            break;

        default:
            // no op
    }
});

module.exports = SampleStore;

【问题讨论】:

  • document.querySelector('#react').dataset.domain。在componentDidMount 中获取它,然后将其发送到通量商店。
  • 如果你想以 'flux' 的方式存储它——获取 redux,创建一个域处于初始状态的 reducer。
  • 谢谢。我可以想象如何做到这一点。我现在就试试。我是 ReactJS 的初学者。我尝试了一些flux和redux教程,然后我发现flux对我来说更容易开始(和理解)。你觉得 redux 现在更好了吗?
  • @azium 谢谢。修复。我更新了我的问题,但我没有信心。如果你能看到我的代码,我将不胜感激。如果您发布答案,我会选择最佳答案。
  • Redux 之所以被 Facebook 采用,是因为它比传统的 Flux 容易得多。

标签: laravel reactjs reactjs-flux


【解决方案1】:

您的第二次编辑是“正确”的 Flux 方式,与我在几个大型项目中使用的方式相同。

更简单的替代方法是在 app.js 中获取域并将其作为道具传递给您的 SampleApp。这需要在 JS 执行之前加载刀片模板中的 DOM。既然你已经把你的 JS 放在了底部,你应该很好,但我添加了 window.onload 事件只是为了确保它。

var React = require('react');
var SampleApp = require('./components/SampleApp.react');

function getDomain() {
    return document.getElementById('react').dataset.domain;
}

function initReact() {

    var params = {
        domain: getDomain()
    };

    React.render(
        <SampleApp {...params} />,
        document.getElementById('react')
    );

}

window.onload = function() {
    initReact();
};

现在您可以使用{this.props.domain} 在 SampleApp.reatc.js 中访问您的域值

【讨论】:

  • 谢谢。我现在试试。
猜你喜欢
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 2015-12-25
  • 2023-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多