Reputation: 10156
I want to create a simple Wizard
component. I don't know how to bind handleChange
function for onChange
input event and how to get into passed context (which is my custom class defined somewhere and instanced in ParentClass
).
Uncaught SyntaxError: Unexpected token }
Here's my Wizard
component and simple template that I created to test it:
export class ParentClass extends React.Component {
render() {
let template = `<input value=${context.testVal} onChange=${context.handleChange.bind(context, event)}>`; // how to invoke this code inside Wizard using TestContext class???
let testContext = new TestContext();
return (
<Wizard template={template} context={testContext} />
);
}
}
export class TestContext {
testVal = null;
constructor() {
this.testVal = 10;
}
handleChange(e) {
console.log(e);
}
}
export class Wizard extends React.Component {
context: null;
constructor(props) {
super(props);
this.context = this.props.context;
}
render() {
return (
<div dangerouslySetInnerHTML={{__html: this.props.template}}>
</div>
);
}
}
I use ES2015
and Babel
for compiling.
[edit]
I edited my code and question. I see now what u guys mean saying "remove $".
U didn't understand me. I want to declare HTML
code with some variable bindings (as a string) + some context class that should contain all the logic for declared template. When I have those, I want to pass them as params into Wizard
and use the template to replace the HTML
of this Wizard
(executing JSX
in the same time). In other words. I want generic mechanism for dynamic templates in Wizard
component.
Upvotes: 1
Views: 1500
Reputation: 26807
You're probably much better off just working with JSX here. Here is one example of how to do that:
function Template (props) {
// Though there's no `event` variable that should be getting bound here and
// you'd be better off binding `handleChange` to the instance in
// TestContext's constructor.
return <input
value={props.context.testVal}
onChange={props.context.handleChange.bind(props.context, event)}
/>;
}
export class ParentClass extends React.Component {
render() {
let testContext = new TestContext();
// You could instead create the element here using Template and pass
// that in. You could even pass it as a child of <Wizard> and just
// have Wizard render its children.
return (
<Wizard template={Template} context={testContext} />
);
}
}
// ...
export class Wizard extends React.Component {
// ...
render() {
return (
<div>
<this.props.template context={this.props.context} />
</div>
);
}
}
You could do something like what you actually asked for like this, but it's not going to work the way you expect -- you can't render a function object into a string of HTML (so I just deleted the onChange
part).
export class ParentClass extends React.Component {
render() {
let template = (context) => `<input value=${context.testVal} />`;
let testContext = new TestContext();
return (
<Wizard template={template} context={testContext} />
);
}
}
// ...
export class Wizard extends React.Component {
// ...
render() {
return (
<div dangerouslySetInnerHTML={{__html: this.props.template(this.context)}} />
);
}
}
But really you can probably accomplish what you want much better by just working with JSX.
Upvotes: 1