2014-06-16 3 views
20

반응 성분에 zurb reveal을 양식과 통합하려고합니다.react.js가 zurb reveal modal 양식과 함께 멋지게 연주하는 방법

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 
    ... 

폼 구성 요소를 상위 구성 요소에 직접 렌더링하면 모든 것이 작동합니다. 아무도 제발 도와 줄 수 있니?

+0

- 내 생각은 재단의 조동사가 DOM을 조작하고 반작용하는 것입니다을 수 없습니다 추적 해. – dbau

+1

@ dbau, 맞습니다. – Voldy

+1

http://plnkr.co/edit/Z6y5dI?p=preview 버그를 선보이기도했습니다. https://github.com/facebook/react/issues/1703 및 https://groups.google.com/forum/#!topic/reactjs/qaG_qRMo29o – dbau

답변

12

간단히 말해서, 이것은 잘못된 것입니다. 이것은 이 아니며입니다. 반응이 없습니다.

반응 성분의 dom 노드를 변형시키는 어떤 종류의 플러그인을 사용하면 어떤 방식 으로든 문제를 일으킬 것입니다.

대신해야 할 일은 반응하는 자체 및 보완적인 CSS를 사용하여 모달 대화 상자에서 원하는 방식으로 구성 요소를 배치하는 것입니다.

react의 statics 구성 요소 속성을 사용하는 구성 요소를 작성하여 renderComponent을 래핑하는 두 개의 함수를 정의하여 반응 대화 상자를 표시하거나 숨기는 데 유용한 깨끗한 함수 호출을 제공하는 것이 좋습니다. 여기에 과거에 사용한 적이있는 예가 있습니다. NB : jQuery를 사용하지만 jQuery 코드를 원하지 않으면 jx를 elementById 등의 표준 js API 호출로 바꿀 수 있습니다.

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

을 그리고

MyDialog.close()

대화는 항상 직접 몸 아래에 새 DOM 노드에 연결하여 닫습니다 :

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> 
    } 
}); 

그런 다음 호출하여 대화 상자를 엽니 다 id 'dialog-anchor'. 열려있는 대화 상자를 열면 새로운 소품을 기반으로 DOM을 업데이트합니다 (또는 동일하지 않은 경우).

물론 대화 상자의 내용을 props 인수로 전달하는 것은별로 유용하지 않습니다. 나는 대개 소품으로 url을 제공 할 때 컴포넌트 내에서 ajax 요청을 통해 content를위한 markdown -> html을 파싱하거나 html을 얻도록 아래에 확장한다.

나는 위의 코드가 정확히 당신이 찾고있는 것이 아니라는 것을 알고 있습니다. 그러나 나는 반응이있는 DOM 수정 플러그인을 만드는 좋은 방법이 있다고 생각하지 않습니다. 반응 구성 요소의 DOM 표현이 정적이어서 결코 제 3 자 플러그인에서 조작 할 수 없다고 생각할 수 없습니다. 솔직히 당신이 프레임 워크를 사용하는 이유를 다시 평가해야하는 방식으로 반응을 사용하기를 원한다면 생각합니다.

즉, 위의 코드는 모든 조작이 구성 요소 내부에서 발생하는 대화 상자의 시작 지점이라고 생각합니다.

NB : 코드가 메모리에서 매우 빨리 작성되었으며 실제로 테스트되지 않은 것은 현재 양식이므로 사소한 구문 오류가있는 경우 미안합니다. 여기

+7

나는 당신이 말하는 것이 정확하다는 것을 이해하지만 실제로는 그 질문에 답하지 않습니다. Foundation의 목적은 이와 같이 상용구 용 구성 요소를 롤백 할 필요가 없기 때문입니다. "올바른 방법"이 아니더라도이 방법을 사용할 수있는 방법이 있는지 알아 보는 것은 흥미로울 것입니다. 그냥 내 두 센트. – pech0rin

5

마이크가 한 일을하지만, ZF는 모달 계시 사용하는 방법이다 : 나는이 같은 문제에 봉착

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> 
    ); 
    } 
});