Get refs via function call - reactjs

I'm trying to replicate the React code from this official guide:
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
Basically, I'm using ES5 and tried this:
componentDidMount: function() {
this.searchBox.focus();
},
render: function() {
return (
<input type="text" ref={function(c) {this.searchBox = c}} />
);
}
But I got an error saying:
Uncaught TypeError: Cannot read property 'focus' of undefined
Isn't the code above supposed to be the same like the ES6 version? I don't get it why it's not working. In case you're interested in the full code, here it is: https://jsfiddle.net/xpd85ehx/

ES5 and ES6 arrow notations use a different this.
Specifically, using the arrow notation, this is lexically bound to the surrounding function (so it refers to the class).
Using ES5 you will need to bind this to your function.

The es6 version uses arrow functions, which auto-binds the function to the existing scope. so for example,
function(c) {this.searchBox = c}
is not bound to the instance of the component, while
c => this.searchBox = c
is. In the first example, its hard to know what this is, but in the second, we can be pretty sure that this is a reference to our component`. If you want to make your solution work in es5, you need to manually bind, like this
render: function() {
return (
<input type="text" ref={(function(c) {this.searchBox = c}).bind(this)} />
);
}

Related

What does the : symbol mean in React createClass() method?

Here's some sample code from ReactKungfu:
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
Hello, world! I am a CommentBox.
</div>
);
}
});
What does the : in render: function() signify? I haven't seen this explained in vanilla JS tutorials I have done, although I believe it signifies "[something] in [this other list/range] in Java
The curly brackets you put around the data passed into the function represent a JS object. render is simply a member variable of that object, so the : is to define that variable as the function after it.
It's basically equivalent to let render = function() { ... } outside of an object.

Default values of props in ReactJS

How can I define default values in ReactJS?
var Header = React.createClass({
render: function() {
return (
<h1>{this.props.title} if not defined insert "Title"</h1>
)
}
});
I extremely increased my React skill and as of 2018 this example (I
wrote at the question body) is outdated. You should do it like
#VladyVeselinov shown at the picture using ES6 classes and babel
transforms like babel-class-properties that allow you to make static
fields for your components
Since your example uses the createClass version of creating a component, you can use the getDefaultProps function.
https://facebook.github.io/react/docs/react-without-es6.html#declaring-prop-types-and-default-props
getDefaultProps: function() {
return {
title: 'Title'
};
}

React state - what I am doing wrong?

I am trying to learn reactjs and building small app that takes in names and then shows the names..
I have an input form, and I am able to get data from input form after clicking submit into my state object called names.
however I am stuck on passing the state from the parent to another component that is inside of my ShowNames component:
So, in App, I am doing this render:
render : function() {
return (
<div>
<InputName addToState={this.addToState}/>
<ShowName renderName={this.renderName}/>
</div>
)
}
});
Then ShowName component has following:
var ShowName = React.createClass({
render : function() {
return (
<ListOfNames renderName={this.props.renderName}/>
)
}
});
So I made
var ListOfNames = React.createClass({
render : function() {
return (
<ul renderName={this.props.renderName}>
{Object.keys(this.state.names).map(this.renderName)}
</ul>
)
}
});
But the issue is it says Cannot read property 'names' of null. Can someone help?
You need to initialise the state otherwise the state will be null.
React.createClass({
getInitialState: function() {
return { names: [] };
},
// all the rest here
}
EDIT
after seeing the code I noticed a couple of errors, the updated code is now here: http://jsbin.com/sewoxu/edit?js,output
So what the main error was that the render function of ShowName was using the state to get the names, but the names where passed via property:
<ShowName renderName={this.renderName} names={this.state.names}/>
so in this case to access the names attribute you need to do:
this.props.names
Also in the example I have moved the renderName function inside the ShowName component.
Hope this helps :)

Properties undefined on getInitialState

React noob here, trying to set an initial value for my checkbox control. I set the property and am trying to set the state to the property value using the getInitialState. Problem is, the props seem to be undefined in the getInitialState. I've simplified and created a jsbin to show the issue.https://jsbin.com/cujeveh/edit?html,js,console,output
var testcontrol = React.createClass({
getInitialState: function () {
return { testval: this.props.testval };
},
render: function() {
return (
<input type="checkbox" checked={this.state.testval?"checked":""}}/>
);
}
});
React.render(
<Container lblOn="yup" lblOff="nope"
buttonText="saveit" testval="1" />, document.body);
Also within the jsbin, tried the componentDidMount method with the same result. If I update the getInitialState to replace the prop with a hardcoded value, everything works fine. I did read the React docs here and did see the antipattern statement but am only trying to set the initial state which I understood as okay.
In your example, you're setting testval prop on the <Container> component, but not on the <Chkbox1> component, which is the component that is checking for it. Probably a minor oversight. You just need to change:
<Chkbox1 ref="box1" lblOn={this.props.lblOn}
lblOff={this.props.lblOff} />
to
<Chkbox1 ref="box1" lblOn={this.props.lblOn}
lblOff={this.props.lblOff} testval={this.props.testval}/>

How to use NPM installed react component in JSX?

I'm trying to use a 3rd party react component (react-slick) within my JSX and running into a problem. I'm attempting to use it very similarly to within this example by the app creator (example1.jsx snippet below).
Whenever I do this I get 2 warnings and an error:
Warning: This JSX uses a plain function. Only React components are valid in React's JSX transform.
Warning: Something is calling a React component directly. Use a factory or JSX instead. See: http://fb.me/react-legacyfactory
Uncaught TypeError: Cannot read property '__reactAutoBindMap' of null
I have also tried something similar as example2.jsx, which was a solution found in another Stack Overflow question. However, while no warnings, or errors were thrown, in this case the code did not render at all.
I have tried various methods of using React.createFactory (which shouldn't be used in JSX to begin with), and other finagling but with no results.
This is probably a stupid question but how the hell do I use NPM installed components in my JSX?
example1.jsx:
var React = require('react');
var Slider = require('react-slick');
var SingleItem = React.createClass({
render: function () {
var settings = {
dots: true,
}
return (
<div>
<h3> Image slider with one item at a time</h3>
<Slider dots={true}>
<div><img src="/img/autumn.jpg" alt=""/></div>
<div><img src="/img/sun.jpg" alt=""/></div>
</Slider>
</div>
);
}
});
var App = React.createClass({
render: function () {
return (
<div className='container'>
<SingleItem />
</div>
);
}
});
example2.jsx:
var App = React.createClass({
render: function () {
return (
<div className='container'>
{SingleItem}
</div>
);
}
});
It looks like you aren't actually referencing the slider component. You may find that your solution looks more like
var Slick = require('react-slick');
var Slider = Slick.Slider
Use the debugger to check what object you are actually being given by the require. It is also possible that you need to require a component by directly referencing one of the libraries file e.g.
var Slider = require('./slider.jsx');
Take a look at the lib or dist directory also, you can see the module.exports value for your require.
Use this to include Slick Slider component:
var Slider = React.createFactory(require('react-slick'));

Resources