我无法输入文字字段。但一切似乎都没问题。我甚至在Sandbox中制作了相同的表格,一切运作良好。我只是不知道发生了什么。也许它与状态结构或webpack配置有关,因为我不使用create-react-app,这可能是个问题。 (我是React和英语的新人,对此感到抱歉)。
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);
TextInput.js
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>
);
商品
import { createStore } from 'redux';
import { middleware } from '../middlewares/index';
import { combineReducers } from 'redux';
import departmentsReducer from '../reducers/departments';
import employeesReducer from '../reducers/employees';
import { reducer as formReducer } from 'redux-form';
const reducers = combineReducers({
departmentsReducer,
employeesReducer,
form: formReducer
});
const store = createStore(reducers, middleware);
window.store = store;
export default store;
相对依赖
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-form": "^7.3.0",
webpack.config.js
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});
}
}
}
}