首页 文章

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

提问于
浏览
1

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

单击按钮时,我想要地址,键入要在Web服务上检查的TextField .

但是我似乎无法使用按钮将TextField的值传递给webservice .

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

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

这段代码是这样的:

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 
* 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,它应该转到reducer并改变地址的状态,但这对于每次更改都是愚蠢的,因为值已经存在......无需更改它 .

因此我用一个表单来做到这一点:

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

但这又一个唠叨的消息:

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

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

1 回答

  • 1

    请参阅TextField demo中受控组件的代码 . 在代码中, value prop从状态拉出, onChange 设置为更新状态的函数 .

    您_240080_已将状态映射到 location 道具并且您已设置 value={location.address} ,但 onChange 已分配给 this.keepVal ,它会尝试更新道具,这是不好的 .

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

相关问题