将组件和道具作为参数传递
Passing component and props as arguments
我正在尝试根据 MobX 可观察值在 App.js 中呈现一个组件。我想定义一个采用组件和一些新的自定义道具分配的动作。这是我现在拥有的:
// App.js inside render()
{ ui_store.main_area_sequence }
.
// ui_store.js
// OBSERVABLES / state
main_area_sequence = <ChoosePostType />;
// ACTIONS / state mutators
update_ui_in_main_section(ComponentTag, props) {
this.main_area_sequence = <ComponentTag {props} />
}
组件参数按预期工作。但是我无法使 props 参数起作用。理想情况下,我会用它来构建类似的东西:
<ChildComponentToBeSwitchedIn name={ui_store.name} handleClick={this.handleClick} />
<ChoosePostType />
中的一个按钮可能会将 main_area_sequence
中的可观察值重新分配给上面的点击,举个例子。
有谁知道如何将 prop 赋值作为参数传递以便执行此操作?
如果您不传递 props,则不要包含 props 参数。
update_ui_in_main_section(ComponentTag) {
this.main_area_sequence = <ComponentTag handleClick={this.handleClick} />;
}
我怀疑你想多了。
回想一下,JSX 只是 JavaScript。当您键入此内容时:
<Foo bar={123}>Baz!</Foo>
...你真的在写这个:
React.createElement(Foo, { bar: 123 }, 'Baz!');
但是,如果您要呈现的组件是动态的怎么办?没关系;它仍然有效。例如,假设我们将组件和道具保存在 React 组件的 state
:
中
render() {
return (
<this.state.dynamicComponent
{...this.state.dynamicComponentProps}
name={this.props.name}
onClick={this.handleClick}
/>
);
}
上面的 JSX 翻译成这个 JavaScript:
React.createElement(this.state.dynamicComponent,
{ ...this.state.dynamicComponentProps,
name: this.props.name,
onClick: this.handleClick,
}
);
如您所见,我们从 this.state.dynamicComponentProps
获得道具,但我们还添加了 this.props.name
的 name
道具和 this.handleClick
的 onClick
道具].你可以想象 this.handleClick
调用 this.setState
来更新 dynamicComponent
和 dynamicComponentProps
.
实际上,您不必想象它,因为您可以在下面的代码片段中看到它的工作原理:
class DynamicComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
dynamicComponent: ShowMeFirst,
dynamicComponentProps: { style: { color: 'blue' }},
};
}
render() {
return (
<this.state.dynamicComponent
{...this.state.dynamicComponentProps}
name={this.props.name}
onClick={this.handleClick}
/>
);
}
handleClick() {
this.updateDynamicComponent(ShowMeSecond, { style: { color: 'red' }});
}
updateDynamicComponent(component, props) {
this.setState({
dynamicComponent: component,
dynamicComponentProps: props,
});
}
}
const ShowMeFirst = ({ name, style, onClick }) => (
<button type="button" style={style} onClick={onClick}>
Hello, {name}!
</button>
);
const ShowMeSecond = ({ name, style, onClick }) => (
<button type="button" style={style} onClick={onClick}>
Goodbye, {name}!
</button>
);
ReactDOM.render(<DynamicComponent name="Alice"/>, document.querySelector('div'));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div></div>
我在上面使用了普通的旧 React 状态,但同样的事情也适用于 MobX,如下所示。 (我以前从未使用过 MobX,所以我的代码可能不够地道,但希望你能理解。)
const { action, decorate, observable } = mobx;
const { observer } = mobxReact;
class UIStore {
dynamicComponent = ShowMeFirst;
dynamicComponentProps = { style: { color: 'blue' }};
updateDynamicComponent(component, props) {
this.dynamicComponent = component;
this.dynamicComponentProps = props;
}
}
decorate(UIStore, {
dynamicComponent: observable,
dynamicComponentProps: observable,
updateDynamicComponent: action,
});
const DynamicComponent = observer(({ store, name }) => (
<store.dynamicComponent
{...store.dynamicComponentProps}
name={name}
onClick={() =>
store.updateDynamicComponent(ShowMeSecond, { style: { color: 'red' }})
}
/>
));
const ShowMeFirst = ({ name, style, onClick }) => (
<button type="button" style={{...style}} onClick={onClick}>
Hello, {name}!
</button>
);
const ShowMeSecond = ({ name, style, onClick }) => (
<button type="button" style={{...style}} onClick={onClick}>
Goodbye, {name}!
</button>
);
ReactDOM.render(<DynamicComponent name="Alice" store={new UIStore()} />, document.querySelector('div'));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/mobx/lib/mobx.umd.js"></script>
<script src="https://unpkg.com/mobx-react@5.2.3/index.js"></script>
<div></div>
我不得不在这里使用 decorate
,因为 Stack Overflow 的 Babel 配置不包括装饰器,但我在 CodeSandbox 上发布了与装饰器相同的东西:https://codesandbox.io/s/qlno63zkw4
我正在尝试根据 MobX 可观察值在 App.js 中呈现一个组件。我想定义一个采用组件和一些新的自定义道具分配的动作。这是我现在拥有的:
// App.js inside render()
{ ui_store.main_area_sequence }
.
// ui_store.js
// OBSERVABLES / state
main_area_sequence = <ChoosePostType />;
// ACTIONS / state mutators
update_ui_in_main_section(ComponentTag, props) {
this.main_area_sequence = <ComponentTag {props} />
}
组件参数按预期工作。但是我无法使 props 参数起作用。理想情况下,我会用它来构建类似的东西:
<ChildComponentToBeSwitchedIn name={ui_store.name} handleClick={this.handleClick} />
<ChoosePostType />
中的一个按钮可能会将 main_area_sequence
中的可观察值重新分配给上面的点击,举个例子。
有谁知道如何将 prop 赋值作为参数传递以便执行此操作?
如果您不传递 props,则不要包含 props 参数。
update_ui_in_main_section(ComponentTag) {
this.main_area_sequence = <ComponentTag handleClick={this.handleClick} />;
}
我怀疑你想多了。
回想一下,JSX 只是 JavaScript。当您键入此内容时:
<Foo bar={123}>Baz!</Foo>
...你真的在写这个:
React.createElement(Foo, { bar: 123 }, 'Baz!');
但是,如果您要呈现的组件是动态的怎么办?没关系;它仍然有效。例如,假设我们将组件和道具保存在 React 组件的 state
:
render() {
return (
<this.state.dynamicComponent
{...this.state.dynamicComponentProps}
name={this.props.name}
onClick={this.handleClick}
/>
);
}
上面的 JSX 翻译成这个 JavaScript:
React.createElement(this.state.dynamicComponent,
{ ...this.state.dynamicComponentProps,
name: this.props.name,
onClick: this.handleClick,
}
);
如您所见,我们从 this.state.dynamicComponentProps
获得道具,但我们还添加了 this.props.name
的 name
道具和 this.handleClick
的 onClick
道具].你可以想象 this.handleClick
调用 this.setState
来更新 dynamicComponent
和 dynamicComponentProps
.
实际上,您不必想象它,因为您可以在下面的代码片段中看到它的工作原理:
class DynamicComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
dynamicComponent: ShowMeFirst,
dynamicComponentProps: { style: { color: 'blue' }},
};
}
render() {
return (
<this.state.dynamicComponent
{...this.state.dynamicComponentProps}
name={this.props.name}
onClick={this.handleClick}
/>
);
}
handleClick() {
this.updateDynamicComponent(ShowMeSecond, { style: { color: 'red' }});
}
updateDynamicComponent(component, props) {
this.setState({
dynamicComponent: component,
dynamicComponentProps: props,
});
}
}
const ShowMeFirst = ({ name, style, onClick }) => (
<button type="button" style={style} onClick={onClick}>
Hello, {name}!
</button>
);
const ShowMeSecond = ({ name, style, onClick }) => (
<button type="button" style={style} onClick={onClick}>
Goodbye, {name}!
</button>
);
ReactDOM.render(<DynamicComponent name="Alice"/>, document.querySelector('div'));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div></div>
我在上面使用了普通的旧 React 状态,但同样的事情也适用于 MobX,如下所示。 (我以前从未使用过 MobX,所以我的代码可能不够地道,但希望你能理解。)
const { action, decorate, observable } = mobx;
const { observer } = mobxReact;
class UIStore {
dynamicComponent = ShowMeFirst;
dynamicComponentProps = { style: { color: 'blue' }};
updateDynamicComponent(component, props) {
this.dynamicComponent = component;
this.dynamicComponentProps = props;
}
}
decorate(UIStore, {
dynamicComponent: observable,
dynamicComponentProps: observable,
updateDynamicComponent: action,
});
const DynamicComponent = observer(({ store, name }) => (
<store.dynamicComponent
{...store.dynamicComponentProps}
name={name}
onClick={() =>
store.updateDynamicComponent(ShowMeSecond, { style: { color: 'red' }})
}
/>
));
const ShowMeFirst = ({ name, style, onClick }) => (
<button type="button" style={{...style}} onClick={onClick}>
Hello, {name}!
</button>
);
const ShowMeSecond = ({ name, style, onClick }) => (
<button type="button" style={{...style}} onClick={onClick}>
Goodbye, {name}!
</button>
);
ReactDOM.render(<DynamicComponent name="Alice" store={new UIStore()} />, document.querySelector('div'));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/mobx/lib/mobx.umd.js"></script>
<script src="https://unpkg.com/mobx-react@5.2.3/index.js"></script>
<div></div>
我不得不在这里使用 decorate
,因为 Stack Overflow 的 Babel 配置不包括装饰器,但我在 CodeSandbox 上发布了与装饰器相同的东西:https://codesandbox.io/s/qlno63zkw4