2016-04-08 87 views
0

我正在尝试使用来自API调用的数据填充选择。选择被渲染,然后当数据返回时,我希望它填充选择的选项。当数据返回时,我将tagList设置为状态,并通过this.state.tagList作为组件的支持。但是当我更新状态时,它不更新组件。也收到以下错误:React组件没有在状态变化时更新

Uncaught Invariant Violation: findComponentRoot(..., .3.2.0.0.0.1): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID ``.

**注:不是我的代码。想帮同事带项目**

选择组件:

'use strict' 

import React from 'react'; 
import classNames from 'classnames'; 
//import ReactDOM from 'react-dom'; 

var TagBar = React.createClass({ 

    propTypes: { 
     tagList: React.PropTypes.array.isRequired 
    }, 

    render: function() { 

     return(
       <select ref="tagBar" className="searchbar ui multiple fluid search dropdown" multiple>        
        { 
         this.props.tagList.map(function(tag){ 
          return <option key={tag._id} value={tag.tag}>{tag.tag}</option>; 
         }) 
        }    
       </select> 
     ) 
    } 
}); 

export default TagBar; 

主要成份:

'use strict' 

import React from 'react'; 
import ReactDOM from 'react-dom'; 

import TagBar from '../../components/tagbar'; 

import InterviewAPI from '../api.js'; 

var AddEditQuestion = React.createClass({ 

    propTypes: { 
     action: React.PropTypes.string.isRequired 
    }, 

    getInitialState: function() { 

     var details = {}; 

     switch (this.props.action) {    

      case 'add': 
      //init an empty props object 
      details = { 
       text: '', 
       tech: '', 
       tags: {}, 
       level: 0, 
       answer: ''    
      }    
      break; 

      case 'edit': 
      //the details are passed in as props 
      details = this.props.details 
      break; 

     } 


     //add is the default action 
     return { 
      action: this.props.action, 
      details: details, 
      tagList: [] 
     } 
    }, 

    render: function() { 

     return(
      <div ref="addQuestionModal" className="ui modal addQuestionModal"> 
       <i className="close icon"></i> 
       <div className="header"> 
        {this.state.action} Question 
       </div> 
       <div className="content"> 
        <div className="description"> 
         <div className="ui form"> 
           <div className="field"> 
            <label htmlFor="questionText">Question</label> 
            <textarea id="questionText" value={this.state.details.text}></textarea> 
           </div>       

           <div className="field"> 
            <label htmlFor="questionAnswer">Answer</label> 
            <textarea id="questionAnswer" value={this.state.details.answer}></textarea> 
           </div>  
           <div className="field"> 
            <label htmlFor="questionTags">Tags</label> 
            <TagBar tagType='question' action={this.state.action} tagList={this.state.tagList} />                        
           </div> 
           <div className="ui two column grid"> 
            <div className="row"> 
             <div className="column"> 
              <div className="field"> 
               <label htmlFor="questionTech">Technology</label> 
               <select ref="questionTech" id="questionTech" name="questionTech"> 
                <option value="">select...</option> 
                <option value="js">Javascript</option> 
                <option value="net">.NET</option> 
                <option value="mobile">Mobile</option>                          
               </select> 
              </div> 
             </div> 
             <div className="column"> 
              <div className="field column"> 
                <label htmlFor="questionLevel">Level</label> 
                <select ref="questionLevel" id="questionLevel" name="questionLevel"> 
                 <option value="">select...</option> 
                 <option value="junior">Junior</option> 
                 <option value="senior">Senior</option> 
                </select> 
              </div>           
             </div>           
            </div> 
           </div>                                     
         </div>     
        </div> 
       </div> 
       <div className="actions"> 
        <div className="ui middle aligned two column grid"> 
         <div className="row">        
          <div ref="deleteAction" className="left aligned column"> 
           {/* based on the state of the modal, this will show different buttons */}      
          </div> 
          <div ref="actionButtons" className="right aligned column actionButtons"> 
           {/* based on the state of the modal, this will show different buttons */} 

          </div> 
         </div> 
        </div> 
       </div> 
      </div>    
     )    
    }, 

    componentWillMount: function() { 
     this.getTags(); 
    }, 

    componentDidMount: function() { 
     //initialize select dropdowns 
     $(this.refs.tagBar).dropdown(); 
     $(this.refs.questionTech).dropdown(); 
     $(this.refs.questionLevel).dropdown(); 

     //display the action buttons (based on whether you're adding or editing) 
     this.displayActionButtons(); 

     //once the modal is rendered, go ahead and open it   
     $(this.refs.addQuestionModal).modal('show'); 
    }, 

    getTags: function() { 
     var apiPath = InterviewAPI.routes.basePath + InterviewAPI.routes.realm.questionTags; 

     //make the api call, passing result to callback 
     $.get(apiPath, this.gotTags);   
    }, 
    gotTags: function(result) { 
     var options = []; 

     if (result.length > 0) { 
      //if you got tags back, add them to the dropdown 
      this.setState({ 
       tagList: result 
      });          
     } 
    }, 

    handleAddQuestion: function() { 
     console.log('add question'); 
    }, 

    closeModal: function() { 
     $(this.refs.addQuestionModal).modal('hide'); 
    },  
}); 

export default AddEditQuestion; 

Uncaught Invariant ViolationsetState被称为内gotTags在被抛出主要组成部分。

回答

0

在语义UI中使用模态时,当您使用模态时,它会将其移动到DOM中以“显示”它。因此,虚拟DOM React知道的与真实的DOM不同。这是导致错误被抛出的原因。为了保持模式从DOM移动需要将detachable属性设置为false,如:

$('.addQuestionModal').modal({detachable:false}).modal('show'); 

然后模态是在两个虚拟的和实际的DOM的相同点和反应可以继续与其交互。

0

它看起来像一对夫妇jQuery插件直接编辑DOM,引发反应。看起来你正在使用jQuery UI,这对编辑DOM非常自由...如果可能的话,使用为ReactJs设计的插件。

对于初学者来说,尝试更换如下:与

jQuery的下拉菜单:https://github.com/JedWatson/react-select

jQuery的模态有:https://github.com/reactjs/react-modal

另外,看看反应的自举:http://react-bootstrap.github.io/

+0

此项目正在使用http://semantic-ui.com/ – erichardson30

+0

嗯,这应该有React集成开箱即用。也许你可以尝试用jsfiddle复制这个? 在错误消息中,是否有任何堆栈信息可能导致您访问特定的文件或行号? –

+0

没有堆栈跟踪...但它给出的组件根目录是链接到选择的那个 – erichardson30

相关问题