【问题标题】:redux-form unable to type values in fieldsredux-form 无法在字段中输入值
【发布时间】:2017-02-26 11:41:50
【问题描述】:

我无法使用 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;

组件

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

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

附加的表单组件

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;

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

【问题讨论】:

    标签: reactjs react-redux redux-form


    【解决方案1】:

    Field 组件中删除value 属性,redux-form 处理更新值并将其传递给您传递它的component。我假设这里的想法是提供 initial 值,但这不是这样做的地方。

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

    你也可以在你的FieldFormControl 中将所有的input 属性传递给你的FormControl,这样你就可以得到onFocusonBlur 等,所有这些都是由redux-form 提供的。

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

    如果您想使用值初始化字段,请在使用reduxForm 连接时使用initialValues,如果需要在表单安装后使用initialize

    最后,您使用了两次combineReducers,以至于您的大多数reducer 都以您不希望的方式嵌套。为了简化这一点,我将在您的reducers/index.js 文件中导入routerReducer,并将其添加到您的combineReducers 那里。

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

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

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

    然后,您应该会看到您的所有键都处于您的状态(会话、配置文件、表单、路由等),而不仅仅是默认和路由。

    【讨论】:

    • 感谢您的反馈和提示!我正在进行更正,但即便如此,我仍然无法在表单字段中输入值。更多的是,我从 redux-form docs 站点获取了简单的示例表单,但在我的情况下效果不佳。所以很明显我做错了什么
    • 你的表单在redux Provider里面吗?
    • 是的render( &lt;Provider store={store}&gt; &lt;Router history={history} routes={routes} /&gt; &lt;/Provider&gt;, target );
    • 好的,我明白了。您的 rootReducer 未正确添加到您的商店,这就是您的状态对象中没有正确键的原因。更新答案。
    【解决方案2】:

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

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

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

    例如你的减速器应该有类似这样的:

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

    【讨论】:

    • 感谢您的反馈!我在哪里以及如何更新状态?
    • 嘿,这是 redux 的工作方式:redux.js.org/docs/basics/Reducers.html 我已经更新了我的答案示例代码
    • 谢谢我的想法,只是我无法弄清楚如何处理异步数据。我使用 thunk 作为中间件,并通过 ajax 获取初始数据。现在我如何调度表单动作有点不清楚,因为学习这些东西。
    • 您正确使用的提供的 reducer 会为您处理更新 for 状态,如您在操作日志中所见。你熟悉 redux-form @Xin 吗?使用它的 reducer 为您处理表单状态是通常的用法。 @fefe 问题可能出在您与Field 组件一起使用的component 中。请出示您的表单组件。
    • 我将附加组件,是一个可用于引导程序的覆盖
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多