2017-02-14 8 views
2

レコードを編集するとき、コンポーネントに表示されるデータは小道具に属します。失敗フォームpropType:あなたはonChangeハンドラせずにフォームフィールドにvalue小道具を提供し、私はエラーレコードの編集:小道具と州の間の競合

警告を取得します。これにより、読み取り専用フィールドがレンダリングされます。フィールドを変更可能にする場合は、defaultValueを使用します。それ以外の場合は、onChangeまたはreadOnlyのいずれかを設定します。レンダリング方法がTerritoryDetailであることを確認します。

controlled componentsというドキュメントに基づいて編集レコードコンポーネントを間違った方法で実装したような気がします。

レコードを編集するときに、フィールド値に小道具を使用しないでください。その場合、アプリケーションの状態でレコードの値を取得しますが、アプリケーションの状態をコンポーネントの状態に同期させるにはどうすればよいでしょうか?

さらに、小道具は、選択オプションが編集上でどのような値であるべきかを示します。しかし、コンポーネント状態は、選択オプションの変更を監視するために使用されます。コンポーネントの状態ではなく、アプリケーションの状態によって小道具が設定されている場合、コンポーネントの状態はレコードの小道具をどのように更新しますか?

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import { getTerritory, getTerritoryMetaData, updateTerritory, modal } from '../actions/index'; 
import { Link } from 'react-router'; 
import { reduxForm } from 'redux-form'; 
import TerritoryTabs from './territory-tabs'; 

class TerritoryDetail extends Component { 

    constructor(props) { 
    super(props); 


    this.openSearchUserQueueModal = this.openSearchUserQueueModal.bind(this); 
    this.setAssignedToType = this.setAssignedToType.bind(this); 
    this.onSubmit = this.onSubmit.bind(this); 
    } 
    componentWillMount() { 
    // console.log(this.props); 
    this.props.getTerritory(this.props.params.id); 
    this.props.getTerritoryMetaData(); 
    } 

    renderTerritoryPickList(fieldName) { 
    return this.props.territoryFields.map((territoryField) => { 
     const shouldRender = territoryField.name === fieldName; 
     if (shouldRender) { 
     return territoryField.picklistValues.map((option) => { 
      return<option value={option.value}>{option.label}</option>; 
     }); 
    } 
    }); 
    } 

    setAssignedToType(event) { 
    this.setState({ assignedToType : event.target.value }); 
    } 

    openSearchUserQueueModal(searchType) { 
    this.props.modal({ 
     type: 'SHOW_MODAL', 
     modalType: 'USER_QUEUE_SEARCH', 
     modalProps: {searchType} 
    }) 
    } 

    onSubmit() { 
    console.log('Update button being clicked'); 
    this.props.updateTerritory({ 
     Name: this.refs[ `Name`].value, 
     tpslead__Type__c: this.refs[ `tpslead__Type__c`].value, 
     tpslead__Assigned_To_Type__c: this.refs[ `tpslead__Assigned_To_Type__c`].value, 
     tpslead__Assigned_To__c: this.refs['tpslead__Assigned_To__c'].value, 
     tpslead__Assigned_To_ID__c: this.refs['tpslead__Assigned_To_ID__c'].value 
     }, this.props.params.id); 
    } 

    onChangeTerritoryName(event) { 
    this.props. 
    } 

    render() { 
    if(!this.props.territory) { 
     return <div>Loading...</div>; 
    } 

    return(
     <TerritoryTabs id={this.props.params.id} listTab="detail"> 
     <div className="slds-form"> 
       <div className="slds-form-element"> 
      <div className="slds-form-element__label"> 
        <label className="slds-align-middle" htmlFor="input1">Lead Territory Name</label> 
      </div> 
      <div className="slds-form-element__control"> 
        <input type="text" ref="Name" className="slds-input" value={this.props.territory.Name}/> 
      </div> 
      </div> 
       <div className="slds-form-element"> 
       <label className="slds-form-element__label" htmlFor="input2">Type</label> 
       <div className="slds-form-element__control"> 
        <div className="slds-select_container"> 
         <select ref="tpslead__Type__c" className="slds-select" value={this.props.territory.tpslead__Type__c}> 
        <option></option> 
        {this.renderTerritoryPickList('tpslead__Type__c')} 
         </select> 
        </div> 
       </div> 
       </div> 
       <div className="slds-form-element"> 
       <label className="slds-form-element__label" htmlFor="input3">Assigned to Type</label> 
       <div className="slds-form-element__control"> 
        <div className="slds-select_container"> 
         <select ref="tpslead__Assigned_To_Type__c" onChange={ this.setAssignedToType } className="slds-select" value={this.props.territory.tpslead__Assigned_To_Type__c}> 
          <option></option> 
        {this.renderTerritoryPickList('tpslead__Assigned_To_Type__c')} 
         </select> 
        </div> 
       </div> 
       </div> 
       <div className="slds-form-element"> 
       <label className="slds-form-element__label">Assigned To</label> 
       <div className="slds-form-element__control"> 
       <section className="slds-clearfix"> 
       <input ref="tpslead__Assigned_To__c" value={this.props.territory.tpslead__Assigned_To__c} className="slds-input slds-float--left" style={{maxWidth: '95%'}} disabled/> 
       <input ref="tpslead__Assigned_To_ID__c" value={this.props.territory.tpslead__Assigned_To_ID__c} type="hidden" /> 
       <button onClick={this.openSearchUserQueueModal.bind(this, this.props.territory.tpslead__Assigned_To_Type__c)} className="slds-button slds-button--icon-border slds-float--right" aria-live="assertive" style={{display: 'inline'}}> 
       <svg className="slds-button__icon" aria-hidden="true"> 
        <use xlinkHref={searchIcon}></use> 
       </svg> 
       </button> 
       </section> 
       </div> 
       </div> 
       <div className="slds-form-element slds-p-top--small"> 
      <Link to="/" className="slds-button slds-button--neutral"> 
       Cancel 
      </Link> 
       <button type="button" onClick={this.onSubmit} className="slds-button slds-button--brand">Update</button> 
       </div> 
     </div> 
     </TerritoryTabs> 
    ); 
    } 
} 

function mapStateToProps(state) { 
console.log(state); 

    return { territory: state.territories.single, 
      territoryFields: state.territories.fields 
     }; 

} 

export default connect(mapStateToProps, { getTerritoryMetaData, getTerritory, updateTerritory, modal })(TerritoryDetail); 

答えて

4

制御コンポーネントとは、値とonChangeハンドラの両方を指定したことを意味します。あなたは両方を持っていなければなりません、あるいはReactが文句を言うでしょう。 nullまたはundefinedの値を渡す場合も同様です。その場合は、デフォルトで空の文字列を使用します。例:

0

ゴールデンルールは、データがユーザーの入力によって変更される場合は、状態を使用し、それ以外の場合は、小道具を使用することです。アプリケーション状態とコンポーネント状態の混同を避けるため、アプリケーション状態Reduxストアを呼び出します。

Reduxストアにあるものはすべて、すでにmapStateToPropsの関数を渡して渡すことができます。コンポーネントのコンストラクタでは、単純にそれらを状態に設定します。しかし、小道具は常にあなたがそれを使用している方法ではなく、必要です。コンストラクタメソッドでそれを行うには、単に次の行を追加します。

this.state = { 
    // whatever you want to define goes here 
    // if you want to pass props you don't need to call this, just props.foo 
} 

あなたが問題なくあなたの選択の状態とあなたの入力の状​​態を処理できることを意味します。

あなたの小道具は、ユーザーとのやりとりによって受け取られない限り、新しい小道具を受け取るたびに更新されます。これは、Reduxストアを使用してアクションをディスパッチできることを意味します。