我是redux-form的新手 - 我现在正在尝试掌握预填充数据概念。
http://redux-form.com/6.0.0-rc.1/examples/initializeFromState/
当我测试这段代码时 - 它会中断。
“TypeError:无法读取未定义的属性'数据'”
此示例编写连接/ redux部分的方式与我过去与其他组件的定义方式不同。
// Decorate with reduxForm(). It will read the initialValues prop provided by connect()
InitializeFromStateForm = reduxForm({
form: 'initializeFromState' // a unique identifier for this form
})(InitializeFromStateForm)
// You have to connect() to any reducers that you wish to connect to yourself
InitializeFromStateForm = connect(
state => ({
initialValues: state.account.data // pull initial values from account reducer
}),
{ load: loadAccount } // bind account loading action creator
)(InitializeFromStateForm)
export default InitializeFromStateForm
-
所以我工作的其他形式 - 看起来像这样。
// EditUserForm.js
import React from 'react'
import { Field, reduxForm } from 'redux-form'
import { Row, Col } from 'antd';
import renderField from '../_SharedFormComponents/renderField'
import validate from './validateEditUser'
import warn from './warnEditUser'
const EditUserForm = props => {
const { handleSubmit, pristine, reset, submitting } = props
return (
<form onSubmit={handleSubmit}>
<Row>
<Col xs={24} sm={24} md={12}>
<Field name="firstName" type="text" component={renderField} label="First Name" />
</Col>
<Col xs={24} sm={24} md={12}>
<Field name="lastName" type="text" component={renderField} label="Last Name" />
</Col>
</Row>
<div>
<button type="submit" disabled={submitting}>
Submit
</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>
Clear Values
</button>
</div>
</form>
)
}
export default reduxForm({
form: 'syncValidationEditUser', // a unique identifier for this form
validate, // <--- validation function given to redux-form
warn // <--- warning function given to redux-form
})(EditUserForm)
^然后我有一个shell父母。
// EditProfile.js
import React, { Component } from 'react'
import { withRouter, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchEditProfile } from '../../actions/editProfileAction';
import { Row, Col, Button, Tabs } from 'antd';
// components
import EditUserForm from './EditUserForm'
// this is a class because it needs state
class EditProfile extends Component {
constructor(props, context) {
super(props, context);
this.submitEditProfile = this.submitEditProfile.bind(this);
}
componentDidMount() {
// console.log('this', this)
}
submitEditProfile(data) {
this.props.fetchEditProfile(data);
}
render() {
return (
<div>
<div className="form-components light">
<Row>
<Col xs={24} sm={24} md={10}>
<p>Edit Profile</p>
</Col>
<Col xs={24} sm={24} md={24}>
<Row>
<Col xs={24} sm={24} md={24}>
<EditUserForm onSubmit={this.submitEditProfile} />
</Col>
</Row>
</Col>
</Row>
</div>
</div>
)
}
}
function mapStateToProps(state) {
return {
editProfileData: state.editProfile
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchEditProfile}, dispatch);
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(EditProfile))
-
所以根据我的理解,他们在该演示中编写连接方面的方式是这样的吗?
function mapStateToProps(state) {
return {
initialValues: state.account.data
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ load: loadAccount }, dispatch);
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(EditProfile))
-
但我仍然希望保留收集和处理数据......
function mapStateToProps(state) {
return {
initialValues: state.initProfile,
editProfileData: state.editProfile
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchInitProfile, fetchEditProfile}, dispatch);
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(EditProfile))
并在“compentDidMount或compentWillMount或componentDidUpdate”中调用? this.fetchInitProfile();
.. 我的initProfile操作会是这样的吗?
// InitProfile.js
import axios from 'axios';
export const FETCH_INIT_PROFILE_SUCCESS = 'FETCH_INIT_PROFILE_SUCCESS'
export const FETCH_INIT_PROFILE_FAILURE = 'FETCH_INIT_PROFILE_FAILURE'
export function initProfileSuccess(response) {
return {
type: FETCH_INIT_PROFILE_SUCCESS,
payload: response
}
}
export function initProfileFail(response) {
return {
type: FETCH_INIT_PROFILE_FAILURE,
payload: response
}
}
export function fetchInitProfile(data) {
let url = 'https://api.github.com/users/theoldcounty';
return function (dispatch) {
axios.get(url)
.then(function (response) {
//console.log(response);
dispatch(initProfileSuccess(response));
})
.catch(function (error) {
//console.log(error);
dispatch(initProfileFail(error));
});
}
}
答案 0 :(得分:0)
以下是制作表单的解决方案 - 具有initialValues - 然后能够调用存储数据。
享受。
// EditProfile.js - 将其称为shell -
import React, { Component } from 'react'
import { withRouter, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchEditProfile } from '../../actions/editProfileAction';
import { fetchInitProfile } from '../../actions/initProfileAction';
import { Row, Col, Button, Tabs } from 'antd';
// components
import EditUserSyncValidationForm from './EditUserSyncValidationForm'
// this is a class because it needs state
class EditProfile extends Component {
constructor(props, context) {
super(props, context);
this.submitEditProfile = this.submitEditProfile.bind(this);
this.props.fetchInitProfile(null);//maybe you will send data like the user id here or it may be stored on server side already if they have logged in
}
submitEditProfile(data) {
this.props.fetchEditProfile(data);
}
render() {
const initialValues = this.props.initProfileData.data;
return (
<div>
<div className="form-components light">
<Row>
<Col xs={24} sm={24} md={10}>
<p>Edit Profile</p>
</Col>
<Col xs={24} sm={24} md={24}>
<Row>
<Col xs={24} sm={24} md={24}>
<EditUserSyncValidationForm initialValues={initialValues} onSubmit={this.submitEditProfile} />
</Col>
</Row>
</Col>
</Row>
</div>
</div>
)
}
}
function mapStateToProps(state) {
return {
editProfileData: state.editProfile,
initProfileData: state.initProfile
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({fetchInitProfile, fetchEditProfile}, dispatch);
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(EditProfile))
// EditUserSyncValidation - 这是表单本身
import React from 'react'
import { Field, reduxForm } from 'redux-form'
import { Row, Col } from 'antd';
import renderField from '../_SharedFormComponents/renderField'
import validate from './validateEditUser'
import warn from './warnEditUser'
const EditUserSyncValidationForm = props => {
const { handleSubmit, pristine, reset, submitting } = props
return (
<form onSubmit={handleSubmit}>
<Row>
<Col xs={24} sm={24} md={12}>
<Field name="firstName" type="text" component={renderField} label="First Name" />
</Col>
<Col xs={24} sm={24} md={12}>
<Field name="lastName" type="text" component={renderField} label="Last Name" />
</Col>
</Row>
<Row>
<Col xs={24} sm={24} md={12}>
<Field name="pin" type="text" component={renderField} label="Pin" />
</Col>
<Col xs={24} sm={24} md={12}>
<Field name="email" type="email" component={renderField} label="Email" />
</Col>
</Row>
<Row>
<Col xs={24} sm={24} md={12}>
<Field name="password" type="password" component={renderField} label="Password" />
</Col>
<Col xs={24} sm={24} md={12}>
<Field name="confirmPassword" type="password" component={renderField} label="Confirm Password" />
</Col>
</Row>
<Row>
<Col xs={24} sm={24} md={12}>
<Field name="phoneNumber" type="text" component={renderField} label="Phone Number" />
</Col>
<Col xs={24} sm={24} md={12}>
</Col>
</Row>
<div>
<button type="submit" disabled={submitting}>
Submit
</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>
Clear Values
</button>
</div>
</form>
)
}
export default reduxForm({
form: 'syncValidationEditUser', // a unique identifier for this form
validate, // <--- validation function given to redux-form
warn // <--- warning function given to redux-form
})(EditUserSyncValidationForm)
然后我们有行动。
// editProfileAction.js
import axios from 'axios';
export const FETCH_EDIT_PROFILE_SUCCESS = 'FETCH_EDIT_PROFILE_SUCCESS'
export const FETCH_EDIT_PROFILE_FAILURE = 'FETCH_EDIT_PROFILE_FAILURE'
export function editProfileSuccess(response) {
return {
type: FETCH_EDIT_PROFILE_SUCCESS,
payload: response
}
}
export function editProfileFail(response) {
return {
type: FETCH_EDIT_PROFILE_FAILURE,
payload: response
}
}
export function fetchEditProfile(data) {
let url = '/apicall/editUser';
return function (dispatch) {
axios.get(url)
.then(function (response) {
//console.log(response);
dispatch(editProfileSuccess(response));
})
.catch(function (error) {
//console.log(error);
dispatch(editProfileFail(error));
});
}
}
// initProfileAction.js
import axios from 'axios';
export const FETCH_INIT_PROFILE_SUCCESS = 'FETCH_INIT_PROFILE_SUCCESS'
export const FETCH_INIT_PROFILE_FAILURE = 'FETCH_INIT_PROFILE_FAILURE'
export function initProfileSuccess(response) {
return {
type: FETCH_INIT_PROFILE_SUCCESS,
payload: response
}
}
export function initProfileFail(response) {
return {
type: FETCH_INIT_PROFILE_FAILURE,
payload: response
}
}
export function fetchInitProfile(data) {
let url = 'api/getInitialProfileData';
return function (dispatch) {
axios.get(url)
.then(function (response) {
//console.log(response);
var response = {
"firstName": "Johnny",
"lastName" : "Rockstar",
"pin" : "1234",
"email" : "johnny@bmail.com",
"phoneNumber" : "0202 02002020"
}
dispatch(initProfileSuccess(response));
})
.catch(function (error) {
//console.log(error);
dispatch(initProfileFail(error));
});
}
}
...然后是减速器
// initProfileReducer.js
import { FETCH_INIT_PROFILE_SUCCESS, FETCH_INIT_PROFILE_FAILURE } from '../actions/initProfileAction'
export function initProfileReducer (state = {}, action) {
//console.log('reducer REG act', action)
switch (action.type) {
case FETCH_INIT_PROFILE_SUCCESS:
return {...state, data: action.payload, isProfileInit: true};
case FETCH_INIT_PROFILE_FAILURE:
return {...state, data: action.payload, isProfileInit: false};
default:
return {...state}
}
}
// editProfileReducer.js
import { FETCH_EDIT_PROFILE_SUCCESS, FETCH_EDIT_PROFILE_FAILURE } from '../actions/editProfileAction'
export function editProfileReducer (state = {}, action) {
switch (action.type) {
case FETCH_EDIT_PROFILE_SUCCESS:
return {...state, data: action.payload, isProfileEdited: true};
case FETCH_EDIT_PROFILE_FAILURE:
return {...state, data: action.payload, isProfileEdited: false};
default:
return {...state}
}
}