Javascript Can';t使用redux表单在文本字段中键入

Javascript Can';t使用redux表单在文本字段中键入,javascript,forms,reactjs,redux,Javascript,Forms,Reactjs,Redux,我无法在文本字段中键入。但一切似乎都很好。我甚至在沙盒中制作了同样的表单,一切都很好。我只是不知道发生了什么事。可能与状态结构或网页包配置有关,因为我不使用CreateReact应用程序,这可能是一个问题。 (我是英语和英语新手,对此我很抱歉) SendForm.js import React, { Component } from 'react'; import { Field, reduxForm } from 'redux-form'; import { TextInput } from

我无法在文本字段中键入。但一切似乎都很好。我甚至在沙盒中制作了同样的表单,一切都很好。我只是不知道发生了什么事。可能与状态结构或网页包配置有关,因为我不使用CreateReact应用程序,这可能是一个问题。 (我是英语和英语新手,对此我很抱歉)

SendForm.js

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


class SendForm extends Component {
    render(){
        return(
            <form onSubmit={this.props.handleSubmit}>
                <Field name="name" component={TextInput} />
                <Field name="email" component={TextInput} />
                <Field name="number" component={TextInput} />
                <button type="submit">ADD EMPLOYEE</button>
            </form>
        )
    }
}

export default reduxForm({
     form: 'sendForm'
})(SendForm);
import React from 'react';

export const TextInput = (field) => (
    <div className="input-row">
        <input {...field.input} type="text" />
        {field.meta.touched && field.meta.error &&
        <span className="error">{field.meta.error}</span>}
    </div>
);
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-form": "^7.3.0",
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    entry: ['babel-polyfill', './src/index.js'],
    output: {
        path: path.join(__dirname, '/dist'),
        filename: 'index_bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: "css-loader"
                })
            },
            {
                test: /\.(sass|scss)$/,
                loader: ExtractTextPlugin.extract([
                    'css-loader',
                    'sass-loader'
                ])
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html'
        }),
        new CopyWebpackPlugin([
            {from: './assets/images', to: 'images'},
            {from: './assets/fonts', to: 'fonts'},
        ]),
        new ExtractTextPlugin({
            filename: 'css/styles.bundle.css',
        }),
    ],
    devServer: {
        proxy: {
            "*": "http://[::1]:3001"
            // "secure": false,
            // "changeOrigin": true
        }
    },
};
相对依赖关系

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


class SendForm extends Component {
    render(){
        return(
            <form onSubmit={this.props.handleSubmit}>
                <Field name="name" component={TextInput} />
                <Field name="email" component={TextInput} />
                <Field name="number" component={TextInput} />
                <button type="submit">ADD EMPLOYEE</button>
            </form>
        )
    }
}

export default reduxForm({
     form: 'sendForm'
})(SendForm);
import React from 'react';

export const TextInput = (field) => (
    <div className="input-row">
        <input {...field.input} type="text" />
        {field.meta.touched && field.meta.error &&
        <span className="error">{field.meta.error}</span>}
    </div>
);
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-form": "^7.3.0",
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    entry: ['babel-polyfill', './src/index.js'],
    output: {
        path: path.join(__dirname, '/dist'),
        filename: 'index_bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: "css-loader"
                })
            },
            {
                test: /\.(sass|scss)$/,
                loader: ExtractTextPlugin.extract([
                    'css-loader',
                    'sass-loader'
                ])
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html'
        }),
        new CopyWebpackPlugin([
            {from: './assets/images', to: 'images'},
            {from: './assets/fonts', to: 'fonts'},
        ]),
        new ExtractTextPlugin({
            filename: 'css/styles.bundle.css',
        }),
    ],
    devServer: {
        proxy: {
            "*": "http://[::1]:3001"
            // "secure": false,
            // "changeOrigin": true
        }
    },
};
webpack.config.js

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


class SendForm extends Component {
    render(){
        return(
            <form onSubmit={this.props.handleSubmit}>
                <Field name="name" component={TextInput} />
                <Field name="email" component={TextInput} />
                <Field name="number" component={TextInput} />
                <button type="submit">ADD EMPLOYEE</button>
            </form>
        )
    }
}

export default reduxForm({
     form: 'sendForm'
})(SendForm);
import React from 'react';

export const TextInput = (field) => (
    <div className="input-row">
        <input {...field.input} type="text" />
        {field.meta.touched && field.meta.error &&
        <span className="error">{field.meta.error}</span>}
    </div>
);
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-form": "^7.3.0",
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    entry: ['babel-polyfill', './src/index.js'],
    output: {
        path: path.join(__dirname, '/dist'),
        filename: 'index_bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: "css-loader"
                })
            },
            {
                test: /\.(sass|scss)$/,
                loader: ExtractTextPlugin.extract([
                    'css-loader',
                    'sass-loader'
                ])
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html'
        }),
        new CopyWebpackPlugin([
            {from: './assets/images', to: 'images'},
            {from: './assets/fonts', to: 'fonts'},
        ]),
        new ExtractTextPlugin({
            filename: 'css/styles.bundle.css',
        }),
    ],
    devServer: {
        proxy: {
            "*": "http://[::1]:3001"
            // "secure": false,
            // "changeOrigin": true
        }
    },
};
父组件

import React, { Component } from 'react';
import Employee from './Employee';
import FontAwesome from 'react-fontawesome';
import { TextField, Grid, Button, Typography } from 'material-ui';
import ExpansionPanel, { ExpansionPanelSummary, ExpansionPanelDetails } from 'material-ui/ExpansionPanel';
import ExpandMoreIcon from 'material-ui-icons/ExpandMore';
import List from 'material-ui/List';
import SendForm from './forms/SendForm';

export default class extends Component{
    constructor(props){
        super(props);
        this.state = {
            isEditable: false
        };
    }
    render(){
        return(
            <ExpansionPanel className="department">
                <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
                    <Grid spacing={16} container>
                        <Grid item sm={10} className="department-name">
                            {
                                this.state.isEditable ?
                                    <TextField defaultValue={this.props.department.name} fullWidth className="update-input" onClick={(e) => {e.stopPropagation()}} inputRef={(el) => this.updateDepartmentInput = el} />
                                    :
                                    <Typography variant="title">
                                        { this.props.department.name }
                                    </Typography>
                            }
                        </Grid>
                        <Grid item sm={1} className="department-update">
                            {
                                this.state.isEditable ?
                                    <div className="save-btn" onClick={ (e)=>{this.saveDepartment(e, this.props.department.id)} }><FontAwesome name="check" ></FontAwesome></div>
                                    :
                                    <div className="update-btn" onClick={ (e)=>{this.updateDepartment(e)} }><FontAwesome name="edit" ></FontAwesome></div>
                            }
                        </Grid>
                        <Grid item sm={1} className="department-delete">
                            <div className="delete-btn" onClick={ ()=>{this.props.deleteDepartment(this.props.department.id)} }><FontAwesome name="times" ></FontAwesome></div>
                        </Grid>
                    </Grid>
                </ExpansionPanelSummary>
                <ExpansionPanelDetails>
                    <Grid container>
                        <Grid item sm={12} className="department-employees">
                            <List component="nav">
                                {
                                    this.props.employees.map((employee, i) => {
                                        if(this.props.department.id === employee.DepartmentId){
                                            return(
                                                <Employee key={i} employee={employee} deleteEmployee={this.props.deleteEmployee} updateEmployee={this.props.updateEmployee}/>
                                            )
                                        }
                                    })
                                }
                            </List>
                        </Grid>
                        <Grid container spacing={24} className="department-add-employee">
                            <Grid item sm={8}><TextField fullWidth type="text" inputRef={el => this.newEmployeeName = el}/></Grid>
                            <Grid item sm={4}><Button fullWidth onClick={this.addEmployee}>Add employee</Button></Grid>
                        </Grid>
                        <SendForm onSubmit={this.addEmployeeTest}/>
                    </Grid>
                </ExpansionPanelDetails>
            </ExpansionPanel>
        )
    }

    addEmployeeTest = (value) => {
        console.log(value); // receiving empty object on form submit
    }

    addEmployee = () => {
        if(this.newEmployeeName.value.length > 0){
            this.props.addEmployee({
                name: this.newEmployeeName.value,
                id: this.props.department.id
            });
            this.newEmployeeName.value = '';
        }
    }

    updateDepartment = (e) => {
        e.stopPropagation();
        this.setState({isEditable: true});
    }

    saveDepartment = (e, id) => {
        e.stopPropagation();
        if(this.updateDepartmentInput.value){
            if(this.updateDepartmentInput.value !== this.props.department.name){
                this.setState({isEditable: false});
                this.props.updateDepartment({
                    name: this.updateDepartmentInput.value,
                    id: id
                });
            } else{
                this.setState({isEditable: false});
            }
        }
    }
}
import React,{Component}来自'React';
从“./Employee”导入员工;
从“react FontAwesome”导入FontAwesome;
从“材料ui”导入{TextField、网格、按钮、排版};
从“材料ui/ExpansionPanel”导入ExpansionPanel,{ExpansionPanelSummary,ExpansionPanelDetails};
从“材料ui图标/ExpandMore”导入ExpandMoreIcon;
从“物料界面/列表”导入列表;
从“./forms/SendForm”导入SendForm;
导出默认类扩展组件{
建造师(道具){
超级(道具);
此.state={
i可编辑:错误
};
}
render(){
返回(
{
这个.state.isEditable?
{e.stopPropagation()}inputRef={(el)=>this.updateDepartmentInput=el}/>
:
{this.props.department.name}
}
{
这个.state.isEditable?
{this.saveDepartment(e,this.props.department.id)}>
:
{this.updateDepartment(e)}}>
}
{this.props.deleteDepartment(this.props.department.id)}>
{
this.props.employees.map((employee,i)=>{
if(this.props.department.id==employee.DepartmentId){
返回(
)
}
})
}
this.newEmployeeName=el}/>
添加员工
)
}
addEmployeeTest=(值)=>{
console.log(value);//在表单提交时接收空对象
}
addEmployee=()=>{
如果(this.newEmployeeName.value.length>0){
这是我的雇员({
名称:this.newEmployeeName.value,
id:this.props.department.id
});
this.newEmployeeName.value='';
}
}
更新的部门=(e)=>{
e、 停止传播();
this.setState({isEditable:true});
}
储蓄部门=(e,id)=>{
e、 停止传播();
if(this.updateDepartmentInput.value){
if(this.updateDepartmentInput.value!==this.props.department.name){
this.setState({isEditable:false});
this.props.updateDepartment({
名称:this.updateDepartmentInput.value,
id:id
});
}否则{
this.setState({isEditable:false});
}
}
}
}

包括呈现表单并具有
handleSubmit
methodOk的组件。顺便说一句,我在这个句柄函数(addEmployeeTest)中收到一个空对象,您正在将
onSubmit
prop传递给您的
SendForm
组件,但是您的
SendForm
组件正在寻找一个
handleSubmit
道具,以传递给这行代码中的
form
元素:
我解决了这个问题。这是我使用的自定义中间件,而不是redux thunk,因此必须在此中间件中解析redux表单操作(传递到下一个方法),否则它将被阻止。