I want to get the text content of the react element. In the example below, I want get: hello 1
var node = <myComponent id={1} />
class myComponent extends React.Component {
render() {
return {
<span> hello {this.props.id} </span>
}
}
I tried to use node.text or ReactDOM.findDOMNode(node).textContent, but it doesn't work. Can I get some help?
Thanks!
Hi i think you should modify your code like below :
<myComponent id={1} />
Try calling your code using:
ReactDOM.render(<MyComponent id={1} />, document.getElementById("root"));
Your code:
class MyComponent extends React.Component {
render() {
return <span>Hello {this.props.id}</span>;
}
}
Link to this code in a Codesandbox:
https://codesandbox.io/s/class-component-dv6fj
Related
I'm trying to render the message with html tags inside it. The rendering is working fine if the string is passed as prop, but when the same is passed from a variable the display text has encoded text.
Any idea how do I get it working in both scenarios.?
class Hello extends React.Component {
render() {
console.log(this.props.name)
return <div>{this.props.name}</div>;
}
}
ReactDOM.render(
<Hello name="<p>How are you?</p>" />,
document.getElementById('container') --> **<p>How are you?</p>**
);
class HelloOther extends React.Component {
render() {
const name = "<p>How are you?</p>"
return <Hello name={name} />;
}
}
ReactDOM.render(
<HelloOther />,
document.getElementById('container2') -- <p>How are you?</p> -- > why?
);
Fiddle link - https://jsfiddle.net/d6s7be1f/2/
class Hello extends React.Component {
createMarkup() {
return {__html: this.props.name};
}
render() {
return <div dangerouslySetInnerHTML={this.createMarkup()} />;
}
}
From React Docs:
In general, setting HTML from code is risky because it’s easy to
inadvertently expose your users to a cross-site scripting (XSS)
attack. So, you can set HTML directly from React, but you have to type
out dangerouslySetInnerHTML and pass an object with a __html key, to
remind yourself that it’s dangerous.
Unless you want to use dangerouslySetInnerHTML, you could use a regex to wrap the string with html tags. This way, you don't have to pass html entities in the string. You just pass the string and wrap the string with html tag using .replace() function.
Since you also want the string to be parsed as HTML, you could pass an extra prop to the Hello component that is then used to wrap the string with the desired html tag and also render the string nested within the desired html tag
function HTMLTag({ tag, children }) {
return React.createElement(tag, null, children);
}
class Hello extends React.Component {
render() {
const { name, tag } = this.props;
const str = name.replace(/(.+)/, `<${tag}>$1</${tag}>`);
return (
<div>
<HTMLTag tag={tag}>{str}</HTMLTag>
</div>
);
}
}
class HelloOther extends React.Component {
render() {
const name = "How are you?";
return <Hello name={name} tag="h3" />;
}
}
ReactDOM.render(
<Hello name="How are you?" tag="p" />,
document.getElementById('container')
);
ReactDOM.render(
<HelloOther />,
document.getElementById('container2')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>
<div id="container2"></div>
I began to learn JavaScript and React these days, I tried to draw some grids in a website and met a problem like this:
Everything works fine when I code like this:
export default class PathfindingVisualizer extends Component {
constructor(props) {
super(props);
this.state = {
nodes: [],
};
}
componentDidMount() {
const nodes = getInitialGrid();
this.setState({ nodes });
}
render() {
const { nodes } = this.state;
console.log(nodes);
return (
<>
<p style={{ fontSize: 40 }}>Visualize Algorithms</p>
<br />
<br />
<div className="node-container">{nodes}</div> // HERE WORKS FINE
</>
);
}
}
And the website turned out to be like this which is fine:
But when I changed the code like this:
render() {
const { nodes } = this.state;
console.log(nodes);
return (
<>
<p style={{ fontSize: 40 }}>Visualize Algorithms</p>
<br />
<br />
<NodeContainer>{nodes}</NodeContainer> // HERE
</>
);
}
}
The grids just disappear, and nothing in <body>:
Could anybody help me? I can't figure out why this is happening.
Class NodeContainer and Node are like this:
export default class NodeContainer extends Component {
render() {
return <div className="node-container"></div>;
}
}
export default class Node extends Component {
render() {
return <div className="node-item"></div>;
}
}
Hey, thank you guys for the answers:) this is my first time to ask a question here. I solved the problem by adding {this.props.xxxxx} as you said and it works.
Corrected codes as following:
...
<br />
<br />
<NodeContainer nodes={nodes}></NodeContainer> // HERE
</>
...
the NodeContainer class:
export default class NodeContainer extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return <div className="node-container">{this.props.nodes}</div>; //HERE
}
}
I didn't use 'this.props.children', but will check out later. I skipped the basic tutorial so I didn't understand how to pass params to class, I checked this video to help myself quickly understand this:
https://www.youtube.com/watch?v=ICmMVfKjEuo&list=PLN3n1USn4xlntqksY83W3997mmQPrUmqM&index=5&t=0s
For this you need to call children inprops
export default class NodeContainer extends Component {
render() {
return <div className="node-container">{this.props.children}</div>;
}
}
I don't see where the Node class is being referenced so I'm not sure that's relevant.
Your issue is that the your passing the nodes component to the NodeContainer component, but not rendering it in NodeContainer. You should look into how props are passed to components - they appear as this.props.children on the component. Your code should look like this.
export default class NodeContainer extends Component {
render() {
return <div className="node-container">{this.props.children}</div>;
}
}
If you're wondering how nodes appears as this.props.children, it's because of how React treats components. You can achieve the same thing by passing it into children explicitly as a prop.
Dude, in reactJS, there's should be data to be pass from your Parent element to your Children element.
In your case to be able to show the data you want,
you need to pass your state from the <PathFindingVisualizer /> to your <NodeContainer />, which you have done it by using node as a children between <NodeContainer /> tag. And you forget the second step,
You need to access the data you have passed inside <NodeContainer /> class you made. How? just access it by using this.props.children.
here's the example.
export default class NodeContainer extends Component {
render() {
return <div className="node-container">{this.props.children}</div>
}
}
Problem solved.
as a reference see this. https://learn.co/lessons/react-this-props-children
I'm developing a more complex example of passing props from a component to another. In this case, it's the content of an array(when I click on that content) to a <div>.
You can find the code here: https://codesandbox.io/s/509j5npkwx
(Please check the code in the link above)
TextBox <div> component:
export class TextBox extends React.Component {
constructor(props) {
super(props);
this.state = {
content: "Select A Node To See Its Data Structure Here..."
};
this.changeContent = this.changeContent.bind(this);
}
changeContent(newContent) {
this.setState({
content: newContent
});
}
render() {
return (
<div className="padd_top">
<div className="content_box">{this.state.content}</div>
</div>
);
}
}
export default TextBox;
FileTree component:
export class FileTree extends React.Component {
constructor(props) {
super(props)
this.state = {
activeNode: null
}
this.setActiveNode = this.setActiveNode.bind(this)
}
setActiveNode(name) {
this.setState({ activeNode: name })
}
render() {
return (
<div className="padd_top">{
renderTree(
this.props.root || root,
this.setActiveNode,
this.state.activeNode
)
}
<TextBox />
</div>
)
}
}
I'm trying to do something like this, for further understanding: http://alexcurtis.github.io/react-treebeard/
I understood how to prepare the <div> to receive new information, by substituting the "Select A Node To See Its Data Structure Here..." when I click one of the elements belonging to the file tree.
I also understood how to prepare the file tree to pass content <div>, but in this case, I'm confused about where and how should I apply to the right component.
I'm new to React JS. If you have any tips for me about this issue, I'm very grateful.
Thank you.
I changed a bit the structure of my project, and now I'm looking forward to put <TextBox> and <FileTree> side by side.
More specifically, like this:
export class App extends React.Component {
render() {
return (
<div>
<div className="col-md-12">
<SearchEngine />
</div>
<div className="col-md-6">
<FileTree />
</div>
<div className="col-md-6">
<TextBox content={this.props.activeNode} />
</div>
</div>
);
}
}
I tought it wouldn't be different to pass props to <App>, but again I might be missing something, because it's not passing properly. What is missing here?
Thanks again.
I'm not sure if I understood your question.
Here is my fork: https://codesandbox.io/s/50pv75q8ll
Basically, you pass the activeNode to < TextBox />. Look at line 126 of index.js.
And then, in text_box.js use componentWillReceiveProps() to set the TextBox state with the content prop. Line 18 of text_box.js.
Say I have file Incomplete.jsx and Main.jsx
Incomplete.jsx looks as follows:
<Hey text="Hello World!" />
<Hey text="You made it to the end of the world!" />
Main.jsx looks as follows:
import React, { Component } from 'react';
import './App.css';
import playlist from './Incomplete';
class Hey extends Component {
constructor(props) {
super(props);
}
render() {
const {text} = this.props;
return (
<p>{text}</p>
);
}
}
class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>{playlist}</div>
);
}
}
export default App;
Then how can I make the program in such a way, that React will render
render(){
return (
<div>
<Hey text="Hello World!" />
<Hey text="You made it to the end of the world!" />
</div>
);
}
Instead of
render() {
return (
<div>{playlist}</div>
);
}
by importing Incomplete.jsx?
Because right now the code doesn't work.
And is something like this even possible? I know that if I create Incomplete.jsx, then I will get a lot of errors. I see components as functions, so the idea is that Incomplete.jsx is a file with all the 'function calls' and the definition will be in Main.jsx.
One constraint that I have is that I don't want to do any imports in Incomplete.jsx.
It's for a project that teaches children how to use some simple pre-defined React Components by simply calling them in the Incomplete.jsx file.
Your incomplete.jsx should look something like this:
const Playlist = (props) => {
return (
<div>
<Hey text="Hello World!" />
<Hey text="You made it to the end of the world!" />
</div>
)
}
export default Playlist;
If you have your import in your main.jsx like this:
import Playlist from './Incomplete';
You can call your code by using <Playlist /> in the render().
Because your incomplete returns a component, and because we call it like that, you could add properties to it. E.g. <Playlist amountOfNumbers={1} />. Which you can retrieve from the props field in your Playlist
If the component you'd like to render inside your main.jsx is supposed to have it's own state. You can rewrite your Playlist to something like this:
export default class Playlist extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Hey text="Hello World!" />
<Hey text="You made it to the end of the world!" />
</div>
);
}
}
The stateless (first) example, can be done without imports.
I'm trying to solve kind of simple problem: when component is loaded, i need to scroll it to the bottom. But i've wasted ton of hours trying to solve it. I've tried a lot of different ways (scrollIntoView, scrollTop, scrollBy, etc...) but none of them can't do it. Url below is a link to fiddle where i have a simple component and i need Message to be shown. The problem is that i have to scroll about 10 pixels by myself. I would really appreciate if you help me to solve this problem.
class Hello extends React.Component {
componentDidMount() {
const elem = ReactDOM.findDOMNode(this.refs.test);
if (elem) {
elem.scrollIntoView(false);
}
}
render() {
return (
<div>
<div className="test"
ref="test">
Hello {this.props.name}
</div>
<div>Message</div>
</div>
)
}
}
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
JSFiddle
You placed the ref attribute on the wrong place.
Move it one level up in order to catch the whole component, including the "Message" text.
So, basically:
class Hello extends React.Component {
// ...
render() {
return (
<div ref="test">
<div className="test">
Hello {this.props.name}
</div>
<div>Message</div>
</div>
)
}
}
Here's a working jsfiddle demo, forked from yours.
class Hello extends React.Component {
// ...
componentDidUpdate() {
this.scrollDiv.scrollIntoView(false);
}
render() {
return (
<div
ref={(el) => {this.scrollDiv = el}}
>
<div className="test">
Hello {this.props.name}
</div>
<div>Message</div>
</div>
)
}
}
You should scroll only when the component is loaded into DOM filled with all props.
export default class Hello extends React.Component {
constructor(props,context){
super(props,context);
this.isAlreadyLoaded = false;
}
componentWillReceiveProps(nextProps) {
let scrollToElement = document.getElementById("scroll-element");
if (scrollToElement && !isAlreadyLoaded){
this.isAlreadyLoaded = true;
scrollToElement.scrollIntoView(true);
}
}
render(){
return {....}
}
}