React ref undefined - reactjs

so I'm having a little trouble using ref's with React.
All I'm trying to do is print the text content of an element using ref's like this:
export default class SomeClass extends Component {
constructor(props) {
super(props);
this.intro = React.createRef();
console.log(this.intro.textContent);
}
render() {
return (
<div ref={this.intro}>Hi</div>
)
}
}
However, this always prints null or undefined instead of "Hi" which is what I want.

You should use current with ref, like this.ref.current.textContent
Check the stackblitz demo Here
export default class App extends Component {
constructor(props) {
super(props);
this.intro = React.createRef();
}
componentDidMount(){
console.log( this.intro.current.textContent);
}
render() {
return (
<div ref={this.intro}>Hi</div>
)
}
}

Its because you are logging it in constructor. Run the code in componentDidMount lifecyle.
export default class SomeClass extends Component {
constructor(props) {
super(props);
this.intro = React.createRef();
}
componentDidMount(){
console.log(this.intro.textContent);
}
render() {
return (
<div ref={this.intro}>Hi</div>
)
}
}

You are console logging in the constructor before Dom is actually rendered.
Try console logging in an onClick handler instead.
export default class SomeClass extends Component {
constructor(props) {
super(props);
this.intro = React.createRef();
}
print = () => {
console.log(this.intro.textContent);
}
render() {
return (
<div>
<div ref={this.intro}>Hi</div>
<button onClick={this.print}>Print</div>
</div>
)
}
}

Related

React JS Inheritance get data

Hi I am developing an application with React JS.
I have a problem.
TopBottomCard.js
export default class TopBottomCard extends Component {
constructor(props){
super(props)
}
getEnlem(){
return this.props.enlem
}
render() {
return (
<div>
example</div>
)}
Map.js
import TopBottomCard from './TopBottomCard'
export default class Map extends TopBottomCard {
constructor(){
super(this)
}
render() {
const top = new TopBottomCard()
const url = 'https://www.example.com/map.html?'+top.getEnlem+''
console.log(url);
return (
<div style={{height:'100vh'}}>
</div>
)
}
}
When I go to the localhost: 3000 / map page I get an output like this.
Output:
https://www.example.com/map.html?function () { [native code] }
When I change the "url" variable on the Map.js page as follows, it gives an error.
const url = 'https://www.example.com/map.html?'+top.getEnlem()+''
Error code: TypeError: Cannot read property 'enlem' of undefined
How do I solve this?
When you create 'Map' class, make sure the constructor get the props and pass them to the parent, using super(this) will not do the trick.
Also make sure you actually send props to the class you instantiate so it will not be undefined.
class TopBottomCard extends React.Component {
constructor(props){
super(props)
}
getEnlem(){
return this.props.enlem
}
render() {
return (
<div>example</div>
)
}
}
class Map extends TopBottomCard {
constructor(props) { // get the props in this constructor as well
super(props) // and pass them to the parent constructor
}
render() {
const top = new TopBottomCard({}) // you need to send props so it will not be undefined in the component
const url = 'https://www.example.com/map.html?' + top.getEnlem() + ''
return (
<div style={{height:'100vh'}}>
</div>
)
}
}

Reactjs: Parent function call triggered by a child

So I am building my first react project and stumbled upon following problem:
In my App.js (main application) I got a function and render my components:
class App extends Component {
constructor(props) {
super(props);
this.candidateCounter = 0;
this.setCandidateVote = this.setCandidateVote.bind(this);
}
...
setCounter (name) {
this.candidateCounter++;
console.log(this.candidateCounter);
}
render() {
...
<Candidates setCounter={this.setCounter} />
}
}
The child component Candidates.jsx has another function and thus calls another component:
export class Candidates extends React.Component {
constructor(props) {
super(props);
this.AppProps = props;
}
...
registerVote(name) {
...
this.AppProps.setCounter(name);
}
render() {
...
<MyButton id={this.state.candidates[i].name} register={this.registerVote} />
}
And the last component MyButton.jsx looks like this:
export class MyButton extends React.Component {
constructor(props) {
super();
this.ParentProps = props;
this.state = { active: false }
}
buttonActiveHandler = () => {
this.setState({
active: !this.state.active
});
if (this.state.active === false) {
this.ParentProps.register(this.ParentProps.id);
}
else {
...
}
}
render() {
return (
<Button content='Click here' toggle active={this.state.active} onClick={this.buttonActiveHandler} />
);
}
}
I have successfully debugged that all functions calls are working except when the grandchild MyButton has triggered the registerVote() function in my Candidates module. Logging in this method gets printed but it cannot call this.AppProps.setCounter() from the parent App. I receive the following error:
TypeError: Cannot read property 'setCounter' of undefined
I hope this wasn't too complicated explained, any help is appreciated :)
Simply bind the function in the constructor of the class as #qasimalbaqali stated in his comment.
constructor(props) {
super();
this.registerVote = this.registerVote.bind(this);
}

render react const as component

Let say I have this Parent
const Parent = () => <ChildComponent foo={<Button>clic</Button>} />
why would this code work
class ChildComponent extends React.Component {
render() {
return (
<div>
{this.props.foo}
</div>
)
}
}
but this code would not ?
class ChildComponent extends React.Component {
constructor(props) {
super(props)
const ParentButton = this.props.foo
}
render() {
return (
<div>
<ParentButton />
</div>
)
}
}
I need something like the second example in order to add some event to ParentButton.
I'd like to make this example work with class defined component
Update :
Based on answer I now have a partial solution
class ChildComponent extends React.Component {
constructor(props) {
super(props)
this.ParentButton = this.props.foo
}
render() {
return (
<div>
{this.ParentButton}
</div>
)
}
}
You're not assigning ParentButton to the ChildComponent.
What you currently have is a const floating in the constructor since const, let and var keywords are function/block scoped.
this. ParentButton = this.props.foo and succinctly <this. ParentButton > in your render function will get you what you're after.

React: How can you access the class name of a parent component from a child without passing it down as props?

Say you have a parent component:
// ParentComponent
class ParentComponent extends React.Component {
render() {
return(
<ChildComponent/>
)
}
}
From inside the child component, is there a way to access the class name of the parent component without passing this down as props?
// ChildComponent
class ChildComponent extends React.Component {
// ?????
getParentComponentName() {
return this.??? // Should return "ParentComponent"
}
render() {
return(
<div/>
)
}
}
I'd prefer to be able to access this without passing it down as props. Thank you!
You need to access ReactInternalFiber like
class Child extends React.Component {
constructor(props) {
super(props);
this.state = { name: '' }
}
getParentName = () =>{
this.setState({ name: this._reactInternalFiber._debugOwner.type.name })
}
render() {
return (
<div>
<h1>Name: {this.state.name}</h1>
<button onClick={this.getParentName}>Get Parent Name</button>
</div>
)
}
}

Dynamically render a component inside a another component in React

I tried to dynamically pass a reference to a class to a container and render it.
class Test extends React.Component{
render() {
return <div>Test</div>
}
}
class HelloWidget extends React.Component{
constructor(props) {
super(props);
this.state = {
child: Test
};
}
render() {
return <div>{this.state.child}</div>;
}
}
React.render(<HelloWidget />, document.getElementById('container'));
See it at jsfiddle: https://jsfiddle.net/coolshare/jwm6k66c/2720/
It did not render anything...
Any suggestion?
thanks
You can dynamically change the state value in HelloWidget component and that would reflect in Test Component.
Here is the code:
class Test extends React.Component{
render() {
return <div>{this.props.child}</div>
}
}
class HelloWidget extends React.Component{
constructor(props) {
super(props);
this.state = {
child: "Test"
};
}
render() {
return <div>
<Test child={this.state.child}/>
</div>;
}
}
React.render(<HelloWidget />, document.getElementById('container'));
Here is a working fiddle link: https://jsfiddle.net/jayesh24/1uvpg5ej/
You need to use React.createElement to create the new react element.
Like this:
render() {
return <div>hello {React.createElement(this.state.child)}</div>;
}
Check the working fiddle.
Use the Directive of your Test inside the constructor to create that component when you are assigning
this.state = {
child: <Test />
};

Resources