React-Redux 初始化来自 FIeldArray 的 reducer 的值
React-Redux initialize values that come from a reducer for a FIeldArray
我有一份内容证明,你可以在这里看到全部内容:https://codesandbox.io/s/87oyv8p89 …具体来说 containers/Form1.js
我想在这里做的是从 reducer 中获取一组书籍(最终这将由 API 填充,但这又是一个 PoC)。作为其中的一部分,我想为每本书创建一个带有数组元素的字段数组,并且我想将文本字段的值默认为书名,我尝试的方法不起作用——我在想这个吗错误的?有正确的方法吗?
为了后代,我有以下 npm 依赖项:
- 反应
- 反应-dom
- react-redux
- 反应脚本
- redux
- redux 形式
和以下文件(所有文件请参见上面的 link):
src/containers/Form1.js
import React, { Component } from "react";
import { Field, reduxForm, FieldArray } from "redux-form";
import { connect } from "react-redux";
function fetchBooks() {
return {
type: "FETCH_BOOKS",
payload: {} //placeholder
};
}
class Form1 extends Component {
componentDidMount() {}
renderBooks = ({ fields, meta: { error, submitFailed } }) => {
return (
<ul>
{this.props.books.map((book, index) => {
return (
<li key={index}>
<Field
name={`book[${index}].title`}
label={`Title (should be ${book.title})`}
component={this.renderField}
defaultValue={book.title}
type="text"
/>
</li>
);
})}
</ul>
);
};
renderField = field => {
const { meta } = field;
const error = meta.touched && meta.error;
let errorMsg = "";
let formClasses = ["form-group"];
if (error) {
errorMsg = <small className="text-help">{meta.error}</small>;
formClasses.push("has-danger");
}
let type = "text";
if (field.type) {
type = field.type;
}
let fieldElement = (
<input className="form-control" type={type} {...field.input} />
);
return (
<div className={formClasses.join(" ")}>
<label>{field.label}</label>
{fieldElement}
{errorMsg}
</div>
);
};
onSubmit = values => {
console.log(values);
};
render() {
const { handleSubmit } = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmit)}>
<FieldArray name="books" component={this.renderBooks} />
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
);
}
}
function validate(values) {
const errors = {};
return errors;
}
function mapStateToProps(state) {
return { books: state.books };
}
export default reduxForm({
validate,
form: "FormWrapper",
destroyOnUnmount: false,
forceUnregisterOnUnmount: true
})(connect(mapStateToProps, { fetchBooks })(Form1));
src/reducers/index.js
import { combineReducers } from "redux";
import { reducer as formReducer } from "redux-form";
import books from "./books";
const rootReducer = combineReducers({
form: formReducer,
books: books
});
export default rootReducer;
src/reducers/books.js
export default function(state = null, action) {
if (!state) {
state = [
{
title: "Things Fall Apart",
author: "Chinua Achebe",
isbn: "9782330070403"
},
{
title: "A Brave New World",
author: "Aldous Huxley",
isbn: "9781405880275"
},
{
title: "Starship Troopers",
author: "Robert Heinlein",
isbn: "9782290301296"
}
];
}
switch (action.type) {
default:
return state;
break;
}
}
这是一个相当简单的修复!
更新 Form1 组件上的 componentDidMount
会按预期设置数据
componentDidMount() {
const { books, initialize } = this.props;
initialize({ books });
}
我有一份内容证明,你可以在这里看到全部内容:https://codesandbox.io/s/87oyv8p89 …具体来说 containers/Form1.js
我想在这里做的是从 reducer 中获取一组书籍(最终这将由 API 填充,但这又是一个 PoC)。作为其中的一部分,我想为每本书创建一个带有数组元素的字段数组,并且我想将文本字段的值默认为书名,我尝试的方法不起作用——我在想这个吗错误的?有正确的方法吗?
为了后代,我有以下 npm 依赖项:
- 反应
- 反应-dom
- react-redux
- 反应脚本
- redux
- redux 形式
和以下文件(所有文件请参见上面的 link):
src/containers/Form1.js
import React, { Component } from "react";
import { Field, reduxForm, FieldArray } from "redux-form";
import { connect } from "react-redux";
function fetchBooks() {
return {
type: "FETCH_BOOKS",
payload: {} //placeholder
};
}
class Form1 extends Component {
componentDidMount() {}
renderBooks = ({ fields, meta: { error, submitFailed } }) => {
return (
<ul>
{this.props.books.map((book, index) => {
return (
<li key={index}>
<Field
name={`book[${index}].title`}
label={`Title (should be ${book.title})`}
component={this.renderField}
defaultValue={book.title}
type="text"
/>
</li>
);
})}
</ul>
);
};
renderField = field => {
const { meta } = field;
const error = meta.touched && meta.error;
let errorMsg = "";
let formClasses = ["form-group"];
if (error) {
errorMsg = <small className="text-help">{meta.error}</small>;
formClasses.push("has-danger");
}
let type = "text";
if (field.type) {
type = field.type;
}
let fieldElement = (
<input className="form-control" type={type} {...field.input} />
);
return (
<div className={formClasses.join(" ")}>
<label>{field.label}</label>
{fieldElement}
{errorMsg}
</div>
);
};
onSubmit = values => {
console.log(values);
};
render() {
const { handleSubmit } = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmit)}>
<FieldArray name="books" component={this.renderBooks} />
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
);
}
}
function validate(values) {
const errors = {};
return errors;
}
function mapStateToProps(state) {
return { books: state.books };
}
export default reduxForm({
validate,
form: "FormWrapper",
destroyOnUnmount: false,
forceUnregisterOnUnmount: true
})(connect(mapStateToProps, { fetchBooks })(Form1));
src/reducers/index.js
import { combineReducers } from "redux";
import { reducer as formReducer } from "redux-form";
import books from "./books";
const rootReducer = combineReducers({
form: formReducer,
books: books
});
export default rootReducer;
src/reducers/books.js
export default function(state = null, action) {
if (!state) {
state = [
{
title: "Things Fall Apart",
author: "Chinua Achebe",
isbn: "9782330070403"
},
{
title: "A Brave New World",
author: "Aldous Huxley",
isbn: "9781405880275"
},
{
title: "Starship Troopers",
author: "Robert Heinlein",
isbn: "9782290301296"
}
];
}
switch (action.type) {
default:
return state;
break;
}
}
这是一个相当简单的修复!
更新 Form1 组件上的 componentDidMount
会按预期设置数据
componentDidMount() {
const { books, initialize } = this.props;
initialize({ books });
}