i am using plunker editor for react for learning.
I am at beginner stage and trying to work on states with react for which i write this codes but it is not rendering can you help me through please.
var Product = React.createClass({
getInitialState: function(){
return(qty=>0);
},
buy: function(){
this.setState({qty:this.state.qty+1});
},
render:function(){
return (
<div>
<p>Android-Rs.1990</p>
<button onClick={this.buy}>Buy</button>
<h3>Qty:{this.state.qty}</h3>
</div>
);
}
});
React.render(<Product/>,document.getElementById("root"));
Instead of return(qty=>0); use return({qty: 0});
The reason for this is that getInitialState requires an object to be returned but in JavaScript qty=>0 actually creates an anonymous function and would somewhat equal function(qty) { return 0 }
What is this? return(qty=>0);
Do you want to return a boolean? Use >= instead.
If you want to assign the initial value of the state you can just use at the beggining of your component
state={
qty:0,
}
You should return an object with quantity set as 0 as explained here:
https://reactjs.org/docs/react-without-es6.html#setting-the-initial-state
So something like this:
getInitialState: function(){
return { quantity: 0 };
},
getInitialState should return an object,
getInitialState: function(){
return{qty: 0};
},
Related
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.
Looking at Facebook's react example here, I found this code showing how to use mixins to set intervals. I am confused as to what is happening with this.intervals. I understand that state holds render-altering data, and props handle data handed down from a parent component, ideally. I would have used this.props.intervals instead, but what is the difference between the two?
var SetIntervalMixin = {
componentWillMount: function() {
this.intervals = [];
},
setInterval: function() {
this.intervals.push(setInterval.apply(null, arguments));
},
componentWillUnmount: function() {
this.intervals.forEach(clearInterval);
}
};
var TickTock = React.createClass({
mixins: [SetIntervalMixin], // Use the mixin
getInitialState: function() {
return {seconds: 0};
},
componentDidMount: function() {
this.setInterval(this.tick, 1000); // Call a method on the mixin
},
tick: function() {
this.setState({seconds: this.state.seconds + 1});
},
render: function() {
return (
<p>
React has been running for {this.state.seconds} seconds.
</p>
);
}
});
ReactDOM.render(
<TickTock />,
document.getElementById('example')
);
When you use props, you know for 100% certainty the value should will be coming from it's immediate parent component (as a property).
When you see state, you know the value is being born/created within that component it's self.
The key, when state changes, every child below will render if any of their received props change.
Your Mixin is not a normal React class. It is simply an object, so this in the case of this.interval, is a reference to the scope of the object in which the method is being executed - TickTock.
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 :)
I am pretty new to React, what I want to do is periodically generate several numbers and update the view:
<script type="text/jsx">
var ChartFrame = React.createClass({
datagenerator: function(n, itvl){
function randomD(){
data2fill = [];
for(var i=0; i<n; i++){
data.push(Math.random()*10);
}
this.setState({
"data": data
});
}
var counter = setInterval(randomD, itvl);
return counter;
},
getInitialState: function(){
return {
data:(function(){
this.state.counter = this.datagenerator(5, 1000);
return [];
})()
}
},
render: function(){
var ds = this.state.data;
var divs = ds.map(function(d, i){
return <div> d </div>;
});
return (
{divs}
);
}
});
React.render(<ChartFrame />, document.body);
<script>
However, I get the error message below:
Uncaught TypeError: this.datagenerator is not a function
I wonder what is the correct way to define function in JSX?
The way you've declared your function is correct but your entire getInitialState is messed up, yo.
What would be the desired behavior here? Since you've declared a new function it will not have access to the correct this which would be the component unless you .bind() it. Unsure what it does or how it works, read this great article. The code is below
return {
data:(function(){
this.state.counter = this.datagenerator(5, 1000);
return [];
}.bind(this))()
}
However doing that will produce another error for you, this.state is undefined hence you will not be able to set counter on this.state.
this.state is never set in getInitialState since the job of the function is to produce the state. Also you're returning an empty array to the data which will lead to this.state.data be an empty Array.
Furthermore, you might want to start your datagenerator function within the life cycle method #componentDidMount in order for state to have been set and the first render has occurred.
And as a complimentary treat, your code in action!
Hitting a roadbump, I’m seeking some help. I'm starting to move more of my "state" pojo's out of my React components, due to for example being unsure how how my pojo’s setter methods should be utilized now (one may want setter methods to validate, etc.). I now find myself either defying React docs' warning to NEVER touch this.state directly or moving most code except rendering – including state - outside of the React component into my own js variables/objects (and holding a reference to the rendered object then using forceUpdate() to rerender). What is the recommended way to freely use whatever plain old js data/model objects I want, including with setter methods?
This barebones example, where I’m wanting a form-backing data object, demonstrates this difference I’m facing: http://jsfiddle.net/jL0rf0ed/ vs. http://jsfiddle.net/rzuswg9x/. Also pasted the code for the first below.
At the very least, I have this specific question: following a custom/manual update of this.state, does a this.setState(this.state) line, which would be from within the React component, and a component.forceUpdate() line, which would likely be from outside the React component, work just as fast and correctly as the standard this.setState({someKey: someValue})?
Thanks.
//props: dataObj, handleInputChange
test.ComponentA = React.createClass({
getInitialState: function() {
return {
age: 21,
email: 'a#b.com', //TODO make members private
setEmail: function(val) { //TODO utilize this
this.email = val;
if(val.indexOf('#') == -1) {
//TODO set or report an error
}
}
}
},
handleInputChange: function(e) {
this.state[e.target.name]=e.target.value; //defying the "NEVER touch this.state" warning (but it appears to work fine)!
this.setState(this.state); //and then this strange line
},
render: function() {
return (
<div>
<input type='text' name='age' onChange={this.handleInputChange} value={this.state.age}></input>
<input type='text' name='email' onChange={this.handleInputChange} value={this.state.email}></input>
<div>{JSON.stringify(this.state)}</div>
</div>
);
}
});
React.render(<test.ComponentA />, document.body);
For your code example in your pasted snippet, you can do the following.
handleInputChange: function(e) {
var updates = {};
updates[e.target.name] = e.target.value;
this.setState(updates);
},
In your second example, you should never call forceUpdate or setState from outside the component itself. The correct way would be for the state to be contained in whatever renders your component and pass in the data as props.
Usually this means you have a wrapper component.
var RootComponent = React.createClass({
getInitialState: ...
onInputChange: function() {
this.setState({yourKey: yourValue});
},
render: function() {
return <SubComponent yourKey={this.state.yourKey} onInputChange={this.onInputChange} />;
}
};
In your case, I would recommend creating this wrapper component. Another solution is just to rerender the same component into the same DOM node.
test.handleInputChange = function(e) {
// update test.formPojo1 here
React.render(<test.ComponentA dataObj={test.formPojo1} handleInputChange={...} />);
}
Because it is the same component class and DOM node, React will treat it as an update.
Stores
Facebook uses the concept of a Store in their Flux architecture.
Stores are a very targeted POJO. And I find that it is pretty simple to use the Store metaphors without the using the entirety of Flux.
Sample Store
This is a Store that I pulled out of one of our production React apps:
ChatMessageStore = {
chatMessages: [],
callbacks: [],
getAll: function() {
return this.chatMessages;
},
init: function() {
this.chatMessages = window.chat_messages.slice();
return this.emitChange();
},
create: function(message) {
this.chatMessages.push(message);
return this.emitChange();
},
emitChange: function() {
return this.callbacks.forEach(callback, function() {
return callback();
});
},
addChangeListener: function(callback) {
return this.callbacks.push(callback);
},
removeChangeListener: function(callback) {
return this.callbacks = _.without(this.callbacks, callback);
}
};
Hooking it up to a React Component
In your component you can now query the store for its data:
var Chat = React.createClass({
componentWillMount: function() {
return ChatMessageStore.addChangeListener(this._onChange);
},
componentWillUnmount: function() {
return ChatMessageStore.removeChangeListener(this._onChange);
},
getInitialState: function() {
return this.getMessageState();
},
getMessageState: function() {
return {
messages: ChatMessageStore.getAll()
};
}
});
The Component registers a callback with the Store, which is fired on every change, updating the component and obeying the law of "don't modify state."