我有一个数据表" View"链接。单击后,它必须从后端获取数据。但是我在以{React-Redux风格存储response
时遇到了麻烦。
这是数据表的片段:
$("#personTable").dataTable({
"columns" : [
{ "data" : "id", "name":"id" ,
"render": (data, type, full,meta) => {
return '<a href="#/person/view?id='+data+'">View</a>;
}
}
在我的routes.jsx中,我将其定义为转发到PersonForm.jsx
<Route name='personForm' path='/person/view' component={PersonForm}/>
在我的PersonForm组件中,我有:
componentWillMount() {
let personId = this.props.location.query.id
this.props.onInit(personId)
}
在我的PersonFormContainer.jsx中:
export const mapDispatchToProps = (dispatch) => {
return {
onInit: (personId) => {
dispatch(init(personId))
}
}
}
这是我的PersonActions.jsx:
export function init(personId) {
return function (dispatch) {
httpService.request('/person/view/' + personId, {method: 'get'})
.then((response) => {
console.log(response.data) // response.data is correctly returned
dispatch({
type: "PERSON_INIT",
data: response.data
})
}).catch(err => console.log(err))
}
}
在我的PersonReducer.js中:
var Immutable = require('immutable');
let initialState =
Immutable.fromJS({
data: {},
fields: {
name: field.create('name', [validation.REQUIRED])
}
})
export default function (state = initialState, action) {
switch(action.type) {
case PERSON_INIT:
return state.set("data", action.data)
//return state.set("fields", Immutable.fromJS(action.fields))
default:
return state
}
}
现在,问题出现在我的PersonForm.jsx上了。在调用render()时,数据(在我的reducer中)有一些值,但不是字段。我不知道如何将response.data(在我的PersonActions中)转换为Reducer中的字段。像这样:
if (data) {
for (let key in fields) {
fields[key].value = data[key]
}
}
这是我的PersonForm组件:
render() {
let store = this.props.person
let fieldsMap = store.get("fields")
<ImmutableInputText label="Name" field={fieldsMap.get("name")}/>
注意:ImmutableInputText来自我们的模板,如:
<input id={field.name} className="form-control" name={field.name}
value={this.state.value} onBlur={this.handleBlur} onChange={changeHandler}
disabled={disabled}/>
答案 0 :(得分:1)
我试图在不知道响应对象结构的情况下回答这个问题,所以我会根据你的回复更新这个答案。
现在,让我们假设这是您从服务器获得的响应
{
"code": 200,
"message": "success",
"person": {
"name": "John Doe",
"email": "john.doe@gmail.com",
"dob": "1980-01-01",
"gender": "male",
"status": "active",
}
}
在PersonReducer.js
中,您可以执行类似
export default function (state = initialState, action) {
switch(action.type) {
case PERSON_INIT:
return state.set("fields", Immutable.fromJS(action.data.person) )
default:
return state
}
}
但这样做会将现有的fields
对象替换为从服务器收到的数据。
如果您想保留所有现有数据并仅更新已更改或新的数据..,您可以执行类似
的操作case PERSON_INIT:
return state.set("fields", Immutable.fromJS({ ...state.get('fields').toObject(), ...action.data.person }) )
如果您只想更新名称字段,可以执行类似
的操作case PERSON_INIT:
return state.setIn(['fields', 'name'], action.data.person.name );
但是你必须为每个领域做到这一点并且不会非常有效,所以你可以通过这样做来实现这个动态
在PersonActions.jsx
文件中(或您想要此动态字段更新功能的任何位置),您可以将调度代码更改为
dispatch({
type: "PERSON_UPDATE_FIELD",
payload: { field: 'name', value: response.data.person.name }
})
注意:我在这里使用的是payload
而不是data
,我认为最好遵循redux命名惯例,但是你的#&#并没有错39;只要你在整个应用程序中坚持使用相同的约定就行了。
在您的PersonReducer.js
中,您可以拥有类似
case PERSON_UPDATE_FIELD:
return state.setIn(['fields', action.payload.field ], action.payload.value );
祝你好运。