Подтвердить что ты не робот

Как сделать response.js играть хорошо вместе с zurb показать модальную форму

Я пытаюсь интегрировать отображение zurb с формой в компонент реакции. Пока что следующий код правильно отображает модальную форму:

ModalForm = React.createClass({
  handleSubmit: function(attrs) {
    this.props.onSubmit(attrs);
    return false;
  },

  render: function(){
    return(
      <div>
        <a href="#" data-reveal-id="formModal" className="button">Add new</a>
        <div id="formModal" className="reveal-modal" data-reveal>
          <h4>Add something new</h4>
          <Form onSubmit={this.handleSubmit} />
          <a className="close-reveal-modal">&#215;</a>
        </div>
      </div>
    );
  }
});

Компонент Form довольно стандартный:

Form = React.createClass({
  handleSubmit: function() {
    var body = this.refs.body.getDOMNode().value.trim();
    if (!body) {
      return false;
    }
    this.props.onSubmit({body: body});
    this.refs.body.getDOMNode().value = '';
    return false;
  },
  render: function(){
    return(
      <form onSubmit={this.handleSubmit}>
        <textarea name="body" placeholder="Say something..." ref="body" />
        <input type="submit" value="Send" className="button" />
      </form>
    );
  }
}); 

Проблема: Когда я обрабатываю компонент формы в составе модальной формы и вношу что-то в ввод формы, я вижу в исключении консоли Uncaught object. Это стек:

Uncaught object
  invariant
  ReactMount.findComponentRoot
  ReactMount.findReactNodeByID
  getNode
  ...

Если я просто визуализую компонент формы непосредственно в родительском компоненте, тогда все работает. Может ли кто-нибудь помочь?

4b9b3361

Ответ 1

Короче говоря, вы делаете это неправильно, и это не ошибка в реакции.

Если вы используете какой-либо плагин, который модифицирует реагирующие компоненты dom, тогда он будет нарушать вещи так или иначе.

Вместо этого вы должны использовать само реагирование и дополнительный css, чтобы расположить компонент так, как вам хотелось бы для вашего модального диалога.

Я бы предложил создать компонент, который использует свойство компонента statics для определения пары функций, обертывающих renderComponent, чтобы дать вам хороший вызов чистой функции, чтобы показать или скрыть диалоговое окно реакции. Здесь приведен пример, который я использовал в прошлом. NB: он использует jQuery, но вы можете заменить jQ на стандартные js-api-вызовы на такие вещи, как elementById и т.д., Если вам не нужен код jQuery.

window.MyDialog = React.createClass({
    propTypes: {
        title:      React.PropTypes.string.isRequired,
        content:    React.PropTypes.string.isRequired
    },
    statics: {

        // open a dialog with props object as props
        open: function(props) {
            var $anchor = $('#dialog-anchor');
            if (!$anchor.length) {
                $anchor = $('<div></div>')
                    .prop('id', 'dialog-anchor');
                    .appendTo('body');
            }
            return React.renderComponent(
                MyDialog(props),
                $anchor.get(0)
            );
        },

        // close a dialog
        close: function() {
            React.unmountComponentAtNode($('#dialog-anchor').get(0));
        }
    },

    // when dialog opens, add a keyup event handler to body
    componentDidMount: function() {
        $('body').on('keyup.myDialog', this.globalKeyupHandler);
    },

    // when dialog closes, clean up the bound keyup event handler on body 
    componentWillUnmount: function() {
        $('body').off('keyup.myDialog');
    },

    // handles keyup events on body
    globalKeyupHandler: function(e) {
        if (e.keyCode == 27) { // ESC key

            // close the dialog
            this.statics.close();
        }
    },

    // Extremely basic dialog dom layout - use your own
    render: function() {
        <div className="dialog">
            <div className="title-bar">
                <div className="title">{this.props.title}</div>
                    <a href="#" className="close" onClick={this.closeHandler}>
                </div>
            </div>
            <div className="content">
                {this.props.content}
            </div>
        </div>
    }
});

Затем вы открываете диалог, вызывая:

MyDialog.open({title: 'Dialog Title', content: 'My dialog content'});

И закройте его

MyDialog.close()

Диалог всегда присоединяется к новому dom node непосредственно под телом с id 'dialog-anchor'. Если вы откроете диалог, когда он уже открыт, он просто обновит dom на основе новых реквизитов (или нет, если они будут одинаковыми).

Конечно, передача содержимого диалога в качестве аргумента реквизита не особенно полезна. Я обычно простираться ниже либо разобрать уценки. → HTML для содержания или получить некоторые HTML с помощью Ajax запроса внутри компонента при поставке URL в качестве опоры вместо

Я знаю, что приведенный выше код не совсем то, что вы искали, но я не думаю, что есть хороший способ заставить работу, модифицирующую dom-плагин, реагировать. Вы никогда не можете предположить, что dom-представление реагирующего компонента является статическим, и поэтому его нельзя манипулировать сторонним плагином успешно. Я честно думаю, что если вы хотите использовать реакцию таким образом, вы должны переоценить, почему вы используете фреймворк.

Тем не менее, я думаю, что вышеприведенный код является отличной отправной точкой для диалога, в котором все манипуляции происходят внутри компонента, что после всего того, о чем говорит реакция!

NB: код был написан очень быстро из памяти и фактически не протестирован в текущей форме, так что извините, если есть некоторые незначительные синтаксические ошибки или что-то в этом роде.

Ответ 2

Вот как это делал Майк, но используя zf-show modal:

var Dialog = React.createClass({
  statics: {
    open: function(){
      this.$dialog = $('#my-dialog');

      if (!this.$dialog.length) {
        this.$dialog = $('<div id="my-dialog" class="reveal-modal" data-reveal role="dialog"></div>')
          .appendTo('body');
      }

      this.$dialog.foundation('reveal', 'open');

      return React.render(
        <Dialog close={this.close.bind(this)}/>,
        this.$dialog[0]
      );
    },
    close: function(){
      if(!this.$dialog || !this.$dialog.length) {
        return;
      }

      React.unmountComponentAtNode(this.$dialog[0]);
      this.$dialog.foundation('reveal', 'close');
    },
  },
  render : function() {
    return (
      <div>
        <h1>This gets rendered into the modal</h1>
        <a href="#" className="button" onClick={this.props.close}>Close</a>
      </div>
    );
  }
});