redux-form无法在字段中键入值

时间:2017-02-26 11:41:51

标签: reactjs react-redux redux-form

我无法使用redux-form在输入字段中键入值。我有以下减速机

import {combineReducers} from 'redux';
import session from './sessionReducer';
import profile from './profileReducer';
import map from './mapReducer';
import { reducer as formReducer } from 'redux-form'

const rootReducer = combineReducers({
    // short hand property names
    session,
    profile,
    map,
    form: formReducer
})

export default rootReducer;

这是商店

import { createStore, combineReducers, applyMiddleware } from 'redux'
import createLogger from 'redux-logger'
import thunk from 'redux-thunk'
import { routerReducer, routerMiddleware, push } from 'react-router-redux'
import reducers from '../reducers'
import { browserHistory } from 'react-router';

const middleware = [ thunk ];
if (process.env.NODE_ENV !== 'production') {
    middleware.push(createLogger());
}

middleware.push(routerMiddleware(browserHistory));


// Add the reducer to your store on the `routing` key
const store = createStore(
    combineReducers({
        reducers,
        routing: routerReducer
    }),
    applyMiddleware(...middleware),

)

export default store;

成分<​​/ P>

import React, {PropTypes, Component} from 'react';
import Upload from './Upload';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import * as profileActions from '../../../actions/profileActions';
import EventsCalendar from '../../common/EventsCalendar';
import { Field, reduxForm } from 'redux-form'
import ProfileForm from './ProfileForm';

import {
    Form,
    FormGroup,
    FormControl,
    ControlLabel,
    Tabs,
    Tab,
    InputGroup,
    Label,
    HelpBlock,
    Grid,
    Row,
    Button,
    Col

} from 'react-bootstrap';


class Profile extends Component {

    static propTypes = {
        profile: PropTypes.object.isRequired,
    };

    constructor(props) {
        super(props);

        this.state = {
            profile: {
                username: '',
                password: '',
                email: ''
            }
        }
        //this.onUpdate = this.onUpdate.bind(this)
    }

    handleSubmit = (values) => {
        // Do something with the form values
        console.log(values);
    }

    componentDidMount() {
        this.props.actions.getProfile()
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.profile !== this.props.profile) {

        }
    }

    render() {
        console.log(this.props.profile);
        const {profile} = this.props.profile;
        const { handleSubmit } = this.props;

        return (
            <div className="row">
                <Col lg={10}>
                    <Tabs defaultActiveKey={1} id="uncontrolled-tab-example">
                        <Tab eventKey={1} title="Vendor Data">
                            <ProfileForm onSubmit={this.handleSubmit}  data = {this.props.profile}/>
                        </Tab>
                        <Tab eventKey={3} title="Events Calendar">
                            <EventsCalendar/>
                        </Tab>
                    </Tabs>

                </Col>

                <Col lg={2}>
                    <Upload/>
                </Col>
            </div>
        );
    }
}

function mapStateToProps(state) {

    return {
        profile: state.default.profile,
    };
}

function mapDispatchToProps(dispatch) {
    return {
        actions: bindActionCreators(profileActions, dispatch)
    };
}

Profile = reduxForm({
    form: 'profileForm' // a unique name for this form
})(Profile);

export default connect(mapStateToProps, mapDispatchToProps)(Profile);

当我打字时,我在控制台中看到状态正在改变

enter image description here

附加的表单组件

import React, {Component} from 'react';
import {Field, reduxForm} from 'redux-form';
import FieldFormControl from '../../common/FieldFormControl';

import {
    FormGroup,
    FormControl,
    ControlLabel,
    Button

} from 'react-bootstrap';

class ProfileForm extends Component {
    render() {
        const {handleSubmit, profile, pristine, reset, submitting} = this.props;

        return (
            <form onSubmit={handleSubmit}>
                <FormGroup controlId="signup-name">
                    <Field type="text" name="firsname" placeholder="test" value component={FieldFormControl}>Vorname</Field>
                </FormGroup>
                <FormGroup controlId="signup-username">
                    <Field type="text" name="lastname" placeholder={profile.username} value={profile.username} component={FieldFormControl}>Name</Field>
                </FormGroup>
                <FormGroup controlId="signup-email">
                    <Field type="text" name="email" placeholder={profile.username} value={profile.username} component={FieldFormControl}>Vorname</Field>
                </FormGroup>

                <Button
                    bsStyle="primary"
                    type="submit"
                    //disabled={pristine || submitting}
                    block
                >Speichern</Button>
            </form>
        );
    }
}

// Decorate the form component
ProfileForm = reduxForm({
    form: 'profileForm' // a unique name for this form
})(ProfileForm);

export default ProfileForm;

bootstrap覆盖与redux-form

兼容
import React, { Component } from 'react';
import {FormGroup, FormControl, ControlLabel} from 'react-bootstrap';

export default class FieldFormControl extends Component {

    render () {

        const { placeholder, type, input, meta} = this.props;

        return (
            <FormGroup controlId={input.name} validationState={meta.error ? 'error' : 'success'}>
                <ControlLabel>{this.props.children}</ControlLabel>
                <FormControl type={type} placeholder={placeholder} value={input.value} onChange={input.onChange} />
                <FormControl.Feedback />
            </FormGroup>
        );
    }
}

2 个答案:

答案 0 :(得分:1)

我不认为这是redux-form的问题。

相反,我认为您的应用程序会侦听输入的onChange,并将操作分派给redux。所以这是根本原因:你调度onChange动作,导致redux状态更新,(我认为你的代码没有在reducer中改变它),然后,redux刷新渲染UI。

要修复它,您: 通常,当您调度onChange操作时,在reducer中,显式更新yuor redux状态。然后新状态将自动刷新您的UI。

e.g。你的减速机应该有类似的东西:

function myReducer(state = initialState, action) {
  switch (action.type) {
    case MY_INPUT_VALUE_CHANGE:
      return Object.assign({}, state, {
        vornname: action.data
      })
    default:
      return state
  }
}

答案 1 :(得分:1)

value组件中删除Field道具,redux-form句柄更新值并将其传递给您传递给它的component。我假设这里的想法是提供初始值,但这不是那个地方。

<Field type="text" name="email" placeholder={profile.username} component={FieldFormControl}>Vorname</Field>

您还可以将所有input道具传递到FormControl中的FieldFormControl,以便获得onFocusonBlur等所有提供者终极版形式。

<FormControl placeholder={placeholder} {...input} />

如果要使用值初始化字段,请在使用reduxForm进行连接时使用initialValues,或者如果需要在表单安装后进行initialize,则使用{{3}}。

最后,你使用combineReducers两次,这样你的大多数reducer都会以你不想要的方式嵌套。为简化此操作,我会在routerReducer文件中导入reducers/index.js,然后将其添加到combineReducers

const rootReducer = combineReducers({
    // short hand property names
    session,
    profile,
    map,
    form: formReducer,
    routing: routerReducer,
});

然后,在您的商店中,您将拥有

const store = createStore(
    reducers,
    applyMiddleware(...middleware),
);

然后您应该会看到您的所有密钥都在您的状态(会话,个人资料,表单,路由等),而不仅仅是默认和路由。