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

Bon*_*usK 2 reactjs redux material-ui react-redux

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

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

但是,我似乎无法使用按钮将 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)
Run Code Online (Sandbox Code Playgroud)

因此,因为我不希望出现任何错误,所以我还考虑仅针对位置地址更改状态。所以我创建了一个新的操作 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>
    );
}
Run Code Online (Sandbox Code Playgroud)
但又是这个烦人的消息:

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

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

Ken*_*ory 5

请参阅TextField 演示中受控组件的代码。在代码中,valueprop 是从 state 中拉出来的,onChange并被设置为一个更新 state 的函数。

   <div>
    <TextField id="standard-name" label="Name" value={name} onChange={handleChange} />
    <TextField id="standard-uncontrolled" label="Uncontrolled" defaultValue="foo" />
  </div>
Run Code Online (Sandbox Code Playgroud)

你实际上很接近。你已经将 state 映射到你的locationprop 并且你已经设置了value={location.address},但是onChange被分配给了this.keepVal哪些试图更新 props,这是不好的。

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