redux-form是一個非常引人注目的庫,用於爲反應應用程序中的表單提供redux綁定,這應該非常方便。不幸的是,使用圖書館自己的例子,我沒有真正綁定任何東西,這是超方便的。如何將redux-form綁定連接到表單的輸入
我試圖利用項目網站上的示例代碼,並發現多個障礙,儘管試圖忠實地重現它。我在哪裏誤解了這個API?自從演示代碼寫入以來API已經移動了嗎?我是否缺少一些關鍵和明顯的重要知識?
問題1:handleSubmit方法的簽名應該是handleSubmit(data)
。但是handleSubmit目前只接收來自提交操作的React syntheticEvent,並且沒有數據。 (事實上,使用寫入的示例發送兩個單獨的事件,看起來是因爲表單上的onSubmit
堆棧操作和按鈕上的onClick
堆棧。)數據應該來自哪裏,爲什麼我無法訪問把它傳遞給處理程序?
問題2:有一個關鍵的fields
對象必須在父窗體上定義並作爲prop提供給窗體。不幸的是,這個對象的形狀沒有在文檔中解釋,也沒有在其目的中解釋。它基本上是最初的'狀態'對象嗎?用於redux-form的簡單對象容器,以便在運行時用於錯誤等等?我已經通過將fields
上的道具匹配到connectReduxForm
中的字段名稱來阻止錯誤,但由於數據不具有約束力,我假設它不是正確的形狀。
問題3:各字段應該是自動結合到處理程序onBlur
和onChange
,以使它們適當地更新存儲。這從來沒有發生過。 (我們可以看到多虧了終極版開發工具然而,handleSubmit
成功分派initialize
行動,這表明實體店,減速機等基本的管道都在努力。)
問題4:validateContact
是初始化時會觸發一次,但不會再次發生。
這對一個簡單的小提琴來說太複雜了,但是整個回購(它只是基本的ReduxStarterApp,加上這種形式的POC)is available here。
而且,這裏是外部組件:
import React from 'react';
import { connect } from 'react-redux';
import {initialize} from 'redux-form';
import ContactForm from '../components/simple-form/SimpleForm.js';
const mapStateToProps = (state) => ({
counter : state.counter
});
export class HomeView extends React.Component {
static propTypes = {
dispatch : React.PropTypes.func.isRequired,
counter : React.PropTypes.number
}
constructor() {
super();
}
handleSubmit(event, data) {
event.preventDefault();
console.log(event); // this should be the data, but is an event
console.log(data); // no data here, either...
console.log('Submission received!', data);
this.props.dispatch(initialize('contact', {})); // clear form: THIS works
return false;
}
_increment() {
this.props.dispatch({ type : 'COUNTER_INCREMENT' });
}
render() {
const fields = {
name: '',
address: '',
phone: ''
};
return (
<div className='container text-center'>
<h1>Welcome to the React Redux Starter Kit</h1>
<h2>Sample Counter: {this.props.counter}</h2>
<button className='btn btn-default'
onClick={::this._increment}>
Increment
</button>
<ContactForm handleSubmit={this.handleSubmit.bind(this)} fields={fields} />
</div>
);
}
}
export default connect(mapStateToProps)(HomeView);
和內部表單組件:
import React, {Component, PropTypes} from 'react';
import {connectReduxForm} from 'redux-form';
function validateContact(data) {
console.log("validating");
console.log(data);
const errors = {};
if (!data.name) {
errors.name = 'Required';
}
if (data.address && data.address.length > 50) {
errors.address = 'Must be fewer than 50 characters';
}
if (!data.phone) {
errors.phone = 'Required';
} else if (!/\d{3}-\d{3}-\d{4}/.test(data.phone)) {
errors.phone = 'Phone must match the form "999-999-9999"';
}
return errors;
}
class ContactForm extends Component {
static propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired
}
render() {
const { fields: {name, address, phone}, handleSubmit } = this.props;
return (
<form onSubmit={handleSubmit}>
<label>Name</label>
<input type="text" {...name}/> {/* will pass value, onBlur and onChange */}
{name.error && name.touched && <div>{name.error}</div>}
<label>Address</label>
<input type="text" {...address}/> {/* will pass value, onBlur and onChange*/}
{address.error && address.touched && <div>{address.error}</div>}
<label>Phone</label>
<input type="text" {...phone}/> {/* will pass value, onBlur and onChange */}
{phone.error && phone.touched && <div>{phone.error}</div>}
<button type='submit'>Submit</button>
</form>
);
}
}
// apply connectReduxForm() and include synchronous validation
ContactForm = connectReduxForm({
form: 'contact', // the name of your form and the key to
// where your form's state will be mounted
fields: ['name', 'address', 'phone'], // a list of all your fields in your form
validate: validateContact // a synchronous validation function
})(ContactForm);
// export the wrapped component
export default ContactForm;
謝謝你這個精心製作的問題!我遇到同樣的困難,我發現複雜形式的文檔和例子錯綜複雜。在你和@Jonny Buchanan的幫助下,我能夠繼續進行(雖然我有一個複雜的數據結構,但我還沒有完成)。添加[redux devtools擴展](https://github.com/zalmoxisus/redux-devtools-extension)也對調試有很大幫助! –