【问题标题】:Uncaught TypeError: Cannot read property 'touched' of undefined未捕获的类型错误:无法读取未定义的属性“已触及”
【发布时间】:2017-02-25 10:50:42
【问题描述】:

尝试使用 Redux 在 React 中验证我的表单时,我不断收到此 Unknown TypeError 错误,但我找不到解决方案。错误来自这里的EventForm:

<div className={`form-group ${title.touched && title.invalid ? 'has-error' : ''}`}>

并出现在 bundle.js 中。

似乎由于某种原因没有定义“字段”。我不知道为什么。

这是我的表单组件:

   // src/components/Form.js
import React, { Component, PropTypes } from 'react'
import style from './style.css'
import { ControlLabel, FormControl, PageHeader, Grid, Checkbox, Radio, FormGroup, Button, HelpBlock, InputGroup } from 'react-bootstrap'
import DatePicker  from 'react-bootstrap-date-picker';
import FieldGroup from './FieldGroup'
import { reduxForm } from 'redux-form';

function validate(values) {
  const errors = {};

  if (!values.title || values.title.trim() === '') {
    errors.title = 'Enter a Title';
  }
  if (!values.categories || values.categories.trim() === '') {
    errors.categories = 'Enter categories';
  }
  if (!values.content || values.content.trim() === '') {
    errors.content = 'Enter some content';
  }

  return errors;
}


class EventForm extends Component {

  getInitalState() {
    var value = new Date().toISOString();
    return {
      value: value
    }
  }

  handleChange({value}) {
    this.setState({
      value: value
    });
  }

  dateGroup() {
    return (
      <FormGroup>
        <ControlLabel>Label</ControlLabel>
        <DatePicker value={this.state.value} onChange={this.handleChange} />
      </FormGroup>
    );
  }

  render() {
    const { fields: { title, categories, content }, handleSubmit, submitting } = this.props;

    return (
      <div className="container">
      <form onSubmit={() => this.handleSubmit}>
        <div className={`form-group ${title.touched && title.invalid ? 'has-error' : ''}`}>
          <label className="control-label">Title*</label>
          <input type="text" className="form-control" {...title} />
          <div className="help-block">
            {title.touched ? title.error : ''}
          </div>
          <div className="help-block">
          </div>
        </div>

        <div className={`form-group ${categories.touched && categories.invalid ? 'has-error' : ''}`}>
          <label className="control-label">Categories*</label>
          <input type="text" className="form-control" {...categories} />
          <div className="help-block">
            {categories.touched ? categories.error : ''}
          </div>
        </div>

        <div className={`form-group ${content.touched && content.invalid ? 'has-error' : ''}`}>
          <label className="control-label">Content*</label>
          <textarea className="form-control" {...content} />
          <div className="help-block">
            {content.touched ? content.error : ''}
          </div>
        </div>

        <button type="submit" className="btn btn-primary" >Submit</button>
        <Link to="/" className="btn btn-error">Cancel</Link>
      </form>
      </div>
  );
  }
}

export default reduxForm({
  form: 'PostsEventForm',
  fields: ['title', 'categories', 'content'],
  validate
},)(EventForm);

这是我的减速器:

import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';
//combineReducers adds all reducers into a single JSON of reducers
const rootReducer = combineReducers({
 form: formReducer // ← redux-form
});
export default rootReducer;

还有我的 index.js:

import { Router, Route, browserHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
import { Provider } from 'react-redux'
import ReactDOM from 'react-dom'
import React from 'react'
import RegisteredEventOverview from './components/RegisteredEventOverview'
import bootstrap from 'bootstrap/dist/css/bootstrap.css'
import EventForm from './components/EventForm/EventForm'
import configureStore from './store/configureStore.js';

const store = configureStore();

ReactDOM.render(
  <Provider store={store}>
    <EventForm/>
  </Provider>
  ,document.getElementById('root')
);

这是我的 package.json:

{
  "name": "take-me-out",
  "version": "1.0.0",
  "private": true,
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server -d --history-api-fallback --hot --inline --progress --colors --port 3002",
    "build": "NODE_ENV=production webpack --progress --colors"
  },
  "license": "MIT",
  "devDependencies": {
    "babel-core": "^6.5.2",
    "babel-loader": "^6.2.3",
    "babel-plugin-transform-runtime": "^6.5.2",
    "babel-preset-es2015": "^6.5.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-0": "^6.5.0",
    "babel-runtime": "^6.5.0",
    "classnames": "^2.2.3",
    "css-loader": "^0.23.1",
    "file-loader": "^0.8.5",
    "jquery": "^3.1.0",
    "less": "^2.7.1",
    "less-loader": "^2.2.3",
    "postcss-loader": "^0.8.1",
    "react": "^15.3.2",
    "react-bootstrap": "^0.30.3",
    "react-dom": "^15.3.2",
    "react-hot-loader": "^3.0.0-beta.5",
    "react-redux": "^4.4.0",
    "react-revalidator": "^0.1.1",
    "react-router": "^2.0.0",
    "react-router-redux": "^4.0.0",
    "redux": "^3.3.1",
    "redux-actions": "^0.9.1",
    "redux-form": "^6.1.0",
    "redux-revalidate": "^0.1.0",
    "revalidate": "^0.4.1",
    "rucksack-css": "^0.8.5",
    "style-loader": "^0.13.0",
    "url-loader": "^0.5.7",
    "webpack": "^1.12.14",
    "webpack-dev-server": "^1.14.1",
    "webpack-hot-middleware": "^2.7.1"
  },
  "peerDependencies": {
    "revalidate": "<1.0.0",
    "react": "^0.14.0 || ^15.0.0"
  },
  "dependencies": {
    "bootstrap": "^3.3.7",
    "redux-promise": "^0.5.3"
  }
}

【问题讨论】:

  • 扔我们一根骨头?告诉我们你在哪一行得到错误?以及您为调试错误所做的工作?例如,如果错误来自validate,则显然valuesundefined。你查过原因吗?
  • 刚刚编辑了我的帖子,见上文。在我看来,我定义的字段仍未定义,但由于我对 React 和 Redux 很陌生,我不知道为什么。

标签: javascript reactjs redux


【解决方案1】:

不能直接使用

<input type="text" className="form-control" {...title} />

你必须导入 redux-form 字段

import { Field, reduxForm } from 'redux-form'

并在您的表单中使用它们,将您的输入作为组件道具传递:

<Field name="title" component="input" type="text" placeholder="title"/>

这样,Redux-Form 将一些道具传递给字段(在您的情况下为“touched”,用于了解用户是否“触摸”了该输入)

你可以在官方Redux-Form page找到一个很好的例子

【讨论】:

    猜你喜欢
    • 2021-12-22
    • 2015-01-06
    • 2017-07-26
    • 2019-02-26
    • 2021-12-25
    • 1970-01-01
    • 2019-05-17
    相关资源
    最近更新 更多