redux 中的嵌套智能组件
Nested smart components in redux
我试图在 redux 中制作一个可重用的组件。
这背后的想法是我正在创建一个智能组合框并将其多次放置在其他组件或智能组件中。
假设此组合框的唯一工作是显示国家/地区,允许添加新国家/地区并告诉父级选择了哪个国家/地区。
父级不必将可用的国家/地区向下传递到组合框,只需将 onValueChanged 事件传递给组合框,这样父级就知道选择了哪个国家/地区。
这导致以下结构(为了简单起见,这些项目并不是真正的国家/地区,但您应该了解其背后的想法):
//Constants (appConstants.ts)
export const SmartCombobox = {
ADD_ITEM: 'SMART_COMBOBOX/ADD_ITEM'
}
//Action creator (smartComboboxAction.ts)
import { SmartCombobox } from '../constants/appConstants';
export function AddItem() {
return {
type: SmartCombobox.ADD_ITEM
};
}
//Reducer (smartCombobox.ts)
import { SmartCombobox } from '../constants/appConstants';
const initialState = ['Item 1']
export default function items(state = initialState, action) {
switch (action.type) {
case SmartCombobox.ADD_ITEM:
let items = ['Item' + Math.random().toString()]
return state.concat(items);
default:
return state;
}
}
//Container (smartCombobox.ts)
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { default as SmartCombobox } from '../components/combobox';
import * as ComboboxActions from '../actions/smartComboboxAction';
function mapStateToProps(state) {
return {
items: state.items
};
}
function mapDispatchToProps(dispatch) {
return {
comboboxActions: bindActionCreators(<any>ComboboxActions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(SmartCombobox);
然后我就可以在我的组件或智能组件中像这样使用它了。
当我添加一个新项目时,包含我的 smartCombobox 的每个组件都会同步并具有准确的项目数量。
//Component (combobox.tsx)
import * as React from 'react';
interface SmartComboboxProps {
items?: Array<any>,
comboboxActions?: any,
onValueChanged: Function
}
export default class SmartCombobox extends React.Component<SmartComboboxProps, any> {
onValueChanged(event:any) {
let selectedValue = event.target.value;
const { onValueChanged } = this.props;
onValueChanged(selectedValue);
}
componentDidMount() {
// Call value changed for first selected item
this.props.onValueChanged(this.props.items[0]);
}
render() {
const { comboboxActions } = this.props;
let options = this.props.items.map(function (o) {
return <option key={o} value={o}>{o}</option>
});
return (
<div>
<select style={{ width: "200px" }} name="SmartCombobox" onChange={ this.onValueChanged.bind(this) } >
{ options }
</select>
<button onClick={ comboboxActions.AddItem }>Add item</button>
</div>
);
}
}
这是可重用组件的正确方法吗?
或者是否有任何我可能忘记的陷阱?
还有一个想法是组合框应该直接连接到 api 因为应用程序不应该知道这里发生了什么。
但这会打破 flux 的想法,因为我需要在这个组件内部有一个状态等等。
我反对那个想法...
Is this the correct approach for reusable components?
Or are there maybe any pitfalls I might forgot
这个方法不错。
There was also the idea that the combobox should be connected directly to an api because the app shouldn't know whats happening in here.
你就在这里。真相的来源(或者更确切地说真相setter)只需要是一个,因此不能是组件。
我试图在 redux 中制作一个可重用的组件。
这背后的想法是我正在创建一个智能组合框并将其多次放置在其他组件或智能组件中。
假设此组合框的唯一工作是显示国家/地区,允许添加新国家/地区并告诉父级选择了哪个国家/地区。
父级不必将可用的国家/地区向下传递到组合框,只需将 onValueChanged 事件传递给组合框,这样父级就知道选择了哪个国家/地区。
这导致以下结构(为了简单起见,这些项目并不是真正的国家/地区,但您应该了解其背后的想法):
//Constants (appConstants.ts)
export const SmartCombobox = {
ADD_ITEM: 'SMART_COMBOBOX/ADD_ITEM'
}
//Action creator (smartComboboxAction.ts)
import { SmartCombobox } from '../constants/appConstants';
export function AddItem() {
return {
type: SmartCombobox.ADD_ITEM
};
}
//Reducer (smartCombobox.ts)
import { SmartCombobox } from '../constants/appConstants';
const initialState = ['Item 1']
export default function items(state = initialState, action) {
switch (action.type) {
case SmartCombobox.ADD_ITEM:
let items = ['Item' + Math.random().toString()]
return state.concat(items);
default:
return state;
}
}
//Container (smartCombobox.ts)
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { default as SmartCombobox } from '../components/combobox';
import * as ComboboxActions from '../actions/smartComboboxAction';
function mapStateToProps(state) {
return {
items: state.items
};
}
function mapDispatchToProps(dispatch) {
return {
comboboxActions: bindActionCreators(<any>ComboboxActions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(SmartCombobox);
然后我就可以在我的组件或智能组件中像这样使用它了。 当我添加一个新项目时,包含我的 smartCombobox 的每个组件都会同步并具有准确的项目数量。
//Component (combobox.tsx)
import * as React from 'react';
interface SmartComboboxProps {
items?: Array<any>,
comboboxActions?: any,
onValueChanged: Function
}
export default class SmartCombobox extends React.Component<SmartComboboxProps, any> {
onValueChanged(event:any) {
let selectedValue = event.target.value;
const { onValueChanged } = this.props;
onValueChanged(selectedValue);
}
componentDidMount() {
// Call value changed for first selected item
this.props.onValueChanged(this.props.items[0]);
}
render() {
const { comboboxActions } = this.props;
let options = this.props.items.map(function (o) {
return <option key={o} value={o}>{o}</option>
});
return (
<div>
<select style={{ width: "200px" }} name="SmartCombobox" onChange={ this.onValueChanged.bind(this) } >
{ options }
</select>
<button onClick={ comboboxActions.AddItem }>Add item</button>
</div>
);
}
}
这是可重用组件的正确方法吗?
或者是否有任何我可能忘记的陷阱?
还有一个想法是组合框应该直接连接到 api 因为应用程序不应该知道这里发生了什么。
但这会打破 flux 的想法,因为我需要在这个组件内部有一个状态等等。
我反对那个想法...
Is this the correct approach for reusable components? Or are there maybe any pitfalls I might forgot
这个方法不错。
There was also the idea that the combobox should be connected directly to an api because the app shouldn't know whats happening in here.
你就在这里。真相的来源(或者更确切地说真相setter)只需要是一个,因此不能是组件。