如何使用MaterialUI和Redux将TextField更改设置为状态?



使用 React/Redux 和 MaterialUI,我设置了一个组件,该组件需要检查您的位置或根据您输入的地址获取纬度/lng。

单击按钮时,我希望在Web服务上检查输入到TextField中的地址。

但是,我似乎无法使用按钮将文本字段的值获取到Web服务。

所以我试图立即在(状态的)道具中设置值。 这有效,但我确实收到一个错误:

警告:组件正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控制切换到受控(反之亦然)。

这段代码是这样的:

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)

因此,因为我不希望出现任何错误,所以我还考虑仅更改位置地址的状态。 所以我创建了一个新的操作集 LocationAddress,它应该转到化简器并仅更改地址的状态,但这在每次更改时都是愚蠢的,因为值已经存在......无需更改它。

因此,我使用了一个表单来执行此操作:

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>
);
}
但又是这个唠叨的消息:

警告:组件正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控制切换到受控(反之亦然)

那么我该怎么做呢? 任何帮助将不胜感激。

请参阅文本字段演示中受控组件的代码。 在代码中,valueprop 从状态中提取,onChange设置为更新状态的函数。

<div>
<TextField id="standard-name" label="Name" value={name} onChange={handleChange} />
<TextField id="standard-uncontrolled" label="Uncontrolled" defaultValue="foo" />
</div>

你实际上很接近。 您已经将状态映射到location道具并设置了value={location.address},但是onChange被分配给尝试更新道具this.keepVal,这不好。

由于您使用的是 Redux,因此您需要在keepVal中调度一个操作,该操作将使用event.target.value更新state.location.address。 这将确保从状态填充组件value,并且从触发的onChange事件中更新存储。

最新更新