它更像是一个建筑问题,而不是技术问题。我正在开发具有以下结构的应用程序(Standard Redux)。
UserFormContainer-> UserForm->(Fields,RoleField,Group Field)。现在我的所有字段都是哑组件,但角色和组除外,它们依赖于要填充的服务器的数据。根据标准redux,我的状态有单向流,所有数据都通过主容器,哑组件只调度动作。
我的问题是,由于角色和组字段依赖于它的数据的父组件,我如何使这些可重用?什么是最佳做法?
这是我的基本组件的单向流程。
答案 0 :(得分:1)
package main
import (
"fmt"
"gopkg.in/olivere/elastic.v5"
"strconv"
)
type Tweet struct {
User string `json:"user"`
Message string `json:"message"`
}
func main() {
client, err := elastic.NewClient()
if err != nil {
fmt.Println("%v", err)
}
n := 0
for i := 0; i < 1000; i++ {
bulkRequest := client.Bulk()
for j := 0; j < 10000; j++ {
n++
tweet := Tweet{User: "olivere", Message: "Package strconv implements conversions to and from string representations of basic data types. " + strconv.Itoa(n)}
req := elastic.NewBulkIndexRequest().Index("twitter").Type("tweet").Id(strconv.Itoa(n)).Doc(tweet)
bulkRequest = bulkRequest.Add(req)
}
bulkResponse, err := bulkRequest.Do()
if err != nil {
fmt.Println(err)
}
if bulkResponse != nil {
}
fmt.Println(i)
}
}
应该是一个愚蠢的组件,它从RoleField
组件获取数据。 UserForm
应该从商店获取数据并将其作为道具传递给UserForm
。这种方式RoleField
将是可重用的,因为它们可以显示从父组件传递给它们的数据。
<强> UDPATE 强>
您还可以使RoleField
包装容器可以接受自定义表单字段作为子容器。请参阅下面的示例代码
UserForm
答案 1 :(得分:1)
为了使我的组件完全独立,我只是将它作为另一个容器,所有副作用都由动作/动作创建者处理,并且它仍然是可测试的,而数据是由它自己的独立减速器计算的。然后我使用redux将状态作为道具传递。
代码示例
import React from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
class RolesField extends React.Component {
componentWillMount() {
//if not fetched then fetch
this.props.fetchRoles();
}
roles() {
let {roles} = this.props;
if (roles.length > 0) {
const {input, label, placeholder, type, meta: {touched, error, warning}} = this.props;
let rolesUi = roles.map((role, index) => {
return (
<div className="checkbox" key={index}>
<label htmlFor={input.name}>
<input {...input} placeholder={placeholder} type={type}/>
{role.name} <a href="#">( Show Permissions )</a>
</label>
</div>
);
});
return rolesUi;
}
}
render() {
const {input, label, placeholder, type, meta: {touched, error, warning}} = this.props;
return (
<div className="form-group">
<label className="col-sm-2 control-label" htmlFor={input.name}>
Administrative Roles
</label>
<div className="col-sm-10">
{/*This section should be loaded from server,
the component should dispatch the event and role action should load the roles.*/}
{this.roles()}
</div>
</div>
);
}
}
//map state to props.
function mapStateToProps(state) {
return {
roles: state.roles.roles
}
}
function mapDispatchToProps(dispatch) {
let actionCreators = {
fetchRoles
};
return bindActionCreators(actionCreators, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(RolesField);
/*Action Types*/
const ROLE_FETCH_START = 'ROLE_FETCH_START';
const ROLE_FETCH_COMPLETE = 'ROLE_FETCH_COMPLETE';
/*End Action Types*/
/**
* Action Creator
* @returns {{type: string, payload: [*,*,*,*]}}
*/
function fetchRoles() {
const roles = [
{'id': 1, 'name': 'Super Admin'},
{'id': 2, 'name': 'Admin'},
{'id': 3, 'name': 'Manager'},
{'id': 4, 'name': 'Technical Lead'}
];
/*Action*/
return {
type: ROLE_FETCH_COMPLETE,
payload: roles
};
}
/**
* Roles Reducer
* @param state
* @param action
* @returns {*}
*/
export function rolesReducer(state = {roles: [], fetched: false}, action) {
switch (action.type) {
case ROLE_FETCH_COMPLETE :
return {
...state,
fetched: true,
roles: action.payload
};
break;
}
return state;
}
要重新使用redux-form中的组件,我做了
import React from 'react';
import {Field, reduxForm} from 'redux-form';
import {renderInputField, renderDropdownList} from '../../page/components/field.jsx';
import RolesField from '../../page/containers/fields/roles.jsx';
import Box from '../../page/components/box.jsx';
import ActionButtons from '../../page/components/action-buttons';
class UserForm extends React.Component {
actionButtons() {
return [
{
'type' : 'submit',
'label' : 'Save',
'className' : 'btn-primary'
},
{
'type' : 'button',
'label' : 'Cancel',
'className' : 'btn-success',
'onClick' : this.props.reset
},
{
'type' : 'button',
'label' : 'Delete',
'className' : 'btn-danger'
}
]
}
render() {
const { handleSubmit } = this.props;
return (
<form className="form-horizontal" role="form" onSubmit={handleSubmit}>
<Box title="Add New User">
<ActionButtons buttons = {this.actionButtons()} />
<Field
name="roles[]"
component={RolesField}
label="Technical Lead"
type="checkbox"
className="form-control" />
</Box>
</form>
);
}
}
UserForm = reduxForm({
form: 'userForm',
validate
})(UserForm);
export default UserForm;
这是修改后的图表。我不确定这是最佳做法还是有任何与之相关的缺点,但它只适用于我的用例。
状态图表
图表的道歉不太清楚。