I am a newbie in React and I am trying to pass props from one React ponent to another. Please consider my code below and tell me what could I possibly doing wrong. As you will notice, I am trying to do so with this.props.value, but all I got in the console is "undefined". I managed to run the code by putting all HTML elements in one ponent and it was working perfectly fine.
class Editor extends React.Component {
constructor(props) {
super(props);
this.state = {
input: defaultTxt
};
this.inputChanges = this.inputChanges.bind(this);
}
inputChanges(e) {
this.setState({
input: e.target.value
});
}
render() {
return (
<div>
<div id="editorBar">
Editor
<i className="fa fa-expand expand" />
</div>
<textarea
id="editor"
style={editorStyle}
value={this.state.input}
onChange={this.inputChanges}
placeholder={defaultTxt}
/>
</div>
);
}
}
//preview
class Previewer extends React.Component {
render() {
return (
<div>
<div id="previewerBar">
Preview
<i className="fa fa-expand expand" />
</div>
<div
id="preview"
style={viewerStyle}
dangerouslySetInnerHTML={{ __html: this.props.value }}
/>
</div>
);
}
}
//wrapper
class Wrapper extends React.Component {
render() {
return (
<div id="wrapper">
<Editor />
<Previewer />
</div>
);
}
}
const defaultTxt = `Some default text`;
ReactDOM.render(<Wrapper />, document.getElementById('root'));
I am a newbie in React and I am trying to pass props from one React ponent to another. Please consider my code below and tell me what could I possibly doing wrong. As you will notice, I am trying to do so with this.props.value, but all I got in the console is "undefined". I managed to run the code by putting all HTML elements in one ponent and it was working perfectly fine.
class Editor extends React.Component {
constructor(props) {
super(props);
this.state = {
input: defaultTxt
};
this.inputChanges = this.inputChanges.bind(this);
}
inputChanges(e) {
this.setState({
input: e.target.value
});
}
render() {
return (
<div>
<div id="editorBar">
Editor
<i className="fa fa-expand expand" />
</div>
<textarea
id="editor"
style={editorStyle}
value={this.state.input}
onChange={this.inputChanges}
placeholder={defaultTxt}
/>
</div>
);
}
}
//preview
class Previewer extends React.Component {
render() {
return (
<div>
<div id="previewerBar">
Preview
<i className="fa fa-expand expand" />
</div>
<div
id="preview"
style={viewerStyle}
dangerouslySetInnerHTML={{ __html: this.props.value }}
/>
</div>
);
}
}
//wrapper
class Wrapper extends React.Component {
render() {
return (
<div id="wrapper">
<Editor />
<Previewer />
</div>
);
}
}
const defaultTxt = `Some default text`;
ReactDOM.render(<Wrapper />, document.getElementById('root'));
Share
Improve this question
edited Oct 12, 2018 at 10:43
Tu Nguyen
10.2k4 gold badges29 silver badges52 bronze badges
asked Oct 12, 2018 at 10:34
Vo_Vo_
511 gold badge3 silver badges10 bronze badges
3
-
If you want to type something in editor and have that appear in preview you really want to have your state/state methods in
Wrapper
if you want to share the state between the two ponents. – Andy Commented Oct 12, 2018 at 10:39 - 1 docs – xadm Commented Oct 12, 2018 at 10:42
- 1 how did you pass the props to Previewer ponent? I expected <Previewer value={value} /> kind of thing but couldn't find it. – wang Commented Oct 12, 2018 at 10:45
2 Answers
Reset to default 4It should look like this:
class Editor extends React.Component {
render() {
return (
<div>
<div id="editorBar">
Editor
<i className="fa fa-expand expand" />
</div>
<textarea
id="editor"
style={editorStyle}
value={this.props.input}
onChange={this.props.inputChanges}
placeholder={defaultTxt}
/>
</div>
);
}
}
//preview
class Previewer extends React.Component {
render() {
return (
<div>
<div id="previewerBar">
Preview
<i className="fa fa-expand expand" />
</div>
<div
id="preview"
style={viewerStyle}
dangerouslySetInnerHTML={{ __html: this.props.value }}
/>
</div>
);
}
}
//wrapper
class Wrapper extends React.Component {
constructor(props) {
super(props);
this.state = {
input: defaultTxt
};
this.inputChanges = this.inputChanges.bind(this);
}
inputChanges(e) {
this.setState({
input: e.target.value
});
}
render() {
return (
<div id="wrapper">
<Editor input={this.state.input} inputChanges={this.inputChanges}/>
<Previewer value={this.state.input}/>
</div>
);
}
}
const defaultTxt = `Some default text`;
ReactDOM.render(<Wrapper />, document.getElementById('root'));
The idea is that the Wrapper ponent
will be the one which hold the state and control the state change. The Editor and Previewer are its children which receive data to display and invoke the callback prop.
If two ponents share state lift the state to the parent ponent - in this case Wrapper
. And since neither of the two children ponents have state they can be coded as stateless functions.
function Editor({ text, handleChange }) {
return (
<div>
<div id="editorBar">Editor
<i className="fa fa-expand expand" />
</div>
<textarea id="editor" value={text} onChange={handleChange} />
</div>
);
}
function Previewer({ text }) {
return (
<div>
<div id="previewerBar">Preview
<i className="fa fa-expand expand"></i>
</div>
<div id="preview" dangerouslySetInnerHTML={{__html: text}}></div>
</div>
);
}
class Wrapper extends React.Component {
constructor(props) {
super(props);
this.state={ input: props.defaultText }
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.setState({ input: e.target.value });
}
render() {
return (
<div id="wrapper">
<Editor text={this.state.input} handleChange={this.handleChange} />
<Previewer text={this.state.input} />
</div>
);
}
}
const defaultText = 'Some default text';
ReactDOM.render(<Wrapper defaultText={defaultText} />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>