我正在尝试基于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} />
}
component自变量按预期工作。但是我无法使props参数起作用。理想情况下,我会用它来构建类似的内容:
<ChildComponentToBeSwitchedIn name={ui_store.name} handleClick={this.handleClick} />
在一个示例中,<ChoosePostType />
中的一个按钮可能会将main_area_sequence
中的可观察值重新分配给上述内容。
有人知道如何将道具分配作为参数传递吗?
答案 0 :(得分:1)
如果您不传递道具,则不要包含道具参数。
update_ui_in_main_section(ComponentTag) {
this.main_area_sequence = <ComponentTag handleClick={this.handleClick} />;
}
答案 1 :(得分:1)
我怀疑您对此有误解。
回想一下,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
获取道具,但我们还从name
添加了this.props.name
道具,并从onClick
添加了this.handleClick
道具。您可以想象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