2017-12-05 5 views
1

React/ReduxとMaterialUIの使用場所を確認するか、入力した住所に基づいて緯度/経度を取得する必要があるコンポーネントをセットアップしました。MaterialUIとReduxを使用して、TextFieldの変更を状態にする方法を教えてください。

ボタンをクリックすると、 Webサービス上でチェックされるTextFieldに追加します。

しかし、ボタンを使用してWebサービスにTextFieldの値を取得できないようです。

私は(州の)小道具ですぐに値を設定しようとしました。 これは動作しますが、私はエラーを取得する実行します。

Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).

このコードは次のようである:私はまた変更に見えたすべてのエラーをしたくないので、だから、

import React, { Component } from 'react'; 
 
import { connect } from 'react-redux'; 
 
import { Field, reduxForm } from 'redux-form' 
 
import TextField from 'material-ui/TextField'; 
 
import IconButton from 'material-ui/IconButton'; 
 
import PlaceIcon from 'material-ui-icons/Place'; 
 
import SearchIcon from 'material-ui-icons/Search'; 
 

 
import { getLocationByAddress, getLocationByLatLng } from '../actions'; 
 

 

 
/** 
 
* Location Search, Lets the user search for his location and coordinates 
 
* @class LocationSearch 
 
* @extends React.Component 
 
*/ 
 
class LocationSearch extends Component { 
 

 
    /** 
 
    * getLocationByLatLng: uses navigator.geolocation to get the current position of the user <br/> 
 
    * then requests the information from a back-end service to retrieve full location data. 
 
    */ 
 
    getLocationByLatLng() { 
 

 
     let options = { 
 
      enableHighAccuracy: true, 
 
      timeout: 5000, 
 
      maximumAge: 0 
 
     }; 
 

 
     navigator.geolocation.getCurrentPosition(function (pos) { 
 
      console.log(pos.coords); 
 

 
     }, function(err){ 
 
      console.warn(`ERROR(${err.code}): ${err.message}`); 
 
     }, options) 
 
    } 
 

 
    /** 
 
    * getLocationByAddress: uses address to request full location data from back-end service 
 
    */ 
 
    getLocationByAddress = (e) => { 
 
     /* 
 
     console.log(e); 
 
     e.preventDefault(); 
 
     */ 
 

 
     this.props.getLocationByAddress(this.props.location.address); 
 
    }; 
 

 
    keepVal = ({target}) => { 
 

 
     this.props.location.address = target.value; 
 

 
    }; 
 

 
    render() { 
 

 
     const { location } = this.props; 
 

 
     return (
 
      <div className={'locationSearch'}> 
 

 
       <IconButton onClick={this.getLocationByLatLng} color="primary" className={'locationSearch_locationBtn'} aria-label=""> 
 
        <PlaceIcon fontSize={35} /> 
 
       </IconButton>    
 
        <TextField 
 
         value={location.address} 
 
         placeholder={'Voer uw locatie in'} 
 
         margin={'normal'} 
 
         className={'locationSearch_input'} 
 
         onChange={this.keepVal} 
 
        /> 
 
        <IconButton onClick={this.getLocationByAddress} color="primary" className={'locationSearch_searchBtn'} aria-label=""> 
 
         <SearchIcon fontSize={35} /> 
 
        </IconButton> 
 
      </div> 
 
     ); 
 
    } 
 

 
} 
 

 
function mapStateToProps (state) { 
 
    return { 
 
     location: state.location 
 
    } 
 
} 
 

 
export default connect(mapStateToProps, {getLocationByAddress, getLocationByLatLng})(LocationSearch)

位置アドレスのための状態。 私は新しいアクションsetLocationAddressを作成しました。それは減速機に移動し、アドレスの状態だけを変更する必要がありますが、値が既にそこにあるので、すべての変更に愚かなことです...変更する必要はありません。

このように私はこれを行うには、フォームを使用:

getLocationByAddress = (e) => { 
 
    e.preventDefault(); 
 
    const { target } = e; 
 
    this.props.getLocationByAddress(target['locationInput'].value); 
 
}; 
 

 
render() { 
 

 
    const { location } = this.props; 
 

 
    return (
 
     <div className={'locationSearch'}> 
 

 
      <IconButton onClick={this.getLocationByLatLng} color="primary" className={'locationSearch_locationBtn'} aria-label=""> 
 
       <PlaceIcon fontSize={35} /> 
 
      </IconButton> 
 
      <form onSubmit={this.getLocationByAddress}> 
 
       <TextField 
 
        name={'locationInput'} 
 
        value={location.address} 
 
        placeholder={'Voer uw locatie in'} 
 
        margin={'normal'} 
 
        className={'locationSearch_input'} 
 
       /> 
 
       <IconButton color="primary" className={'locationSearch_searchBtn'} aria-label=""> 
 
        <SearchIcon fontSize={35} /> 
 
       </IconButton> 
 
      </form> 
 
     </div> 
 
    ); 
 
}
しかし、再びこのnaggyメッセージ:

Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa)

だから私はこれをどのように行うのですか? ご協力いただければ幸いです。

+0

なぜテキストフィールドの値を小道具に保存していますか?私はreduxも使用しているので、これをsetState – link0047

+0

で状態に保存する必要がありますか? – BonifatiusK

+1

独自の小道具を更新するコンポーネントは、アンチパターンです。あなたがあなたの状態をreduxに格納しているならば、ディスパッチメソッドを使うべきです。 – link0047

答えて

0

の制御されたコンポーネントのコードを参照してください。コードではvalueの支柱は状態から引っ張られ、onChangeは状態を更新する関数に設定されています。

あなたは実際にはかなり近いです。状態をlocation小道具にマッピングし、value={location.address}と設定しましたが、onChangethis.keepValに割り当てられています。これは小道具の更新を試みます。

Reduxを使用しているので、keepValstate.location.addressを、event.target.valueに更新するアクションをディスパッチする必要があります。これにより、コンポーネントvalueが状態から移入され、起動されたonChangeイベントからの変更がストアを更新することが保証されます。

関連する問題