Use props instead of state - javascript

I know if you want to alter something within a component itself you use state, and when the emit is external then u use props to receive it. But today I stumped across this example
var Label = React.createClass({
handleClick: function(){
console.log("Click");
this.props.children = "Text After Click";
this.setState({liked: false});
},
render: function () {
console.log("Render");
return (
<p ref="p" onClick={this.handleClick}>{this.props.children}</p>
);
}
});
Used props instead of state to change the text a value of a button. I'm confused now. The link to the source is here http://myshareoftech.com/2013/12/unit-testing-react-dot-js-with-jasmine-and-karma.html

I don't know about the source but when i tried above code it throws this error:
Uncaught TypeError: Cannot assign to read only property 'children' of object #<Object>.
It should not work because the basic property of the props is, as per DOC:
Props are Read-Only, Whether you declare a component as a function or a class, it must never modify its own props. All React components must act like pure functions with respect to their props.
Check the fiddle for error: https://jsfiddle.net/pjnp6yza/
Reference: https://facebook.github.io/react/docs/components-and-props.html#props-are-read-only

Related

Can't Perform a React State Update on an Unmounted Component. This is a no-op - Mob X Related

I'm currently working on a smart home sort of app and are a beginner, and I'm using mobX to set the active room names.
I set them in the "Dashboard" Component to the title of the container. Then I want to use the variable stored inside to filter through the rooms in another component called "room". If I hard-code the room name it works, but it throws a bunch of errors when I replace the room name with the actual variable.
I've already tried declaring things within componentWillUnmount() but it hasn't worked so far.
This is where I set the variable
handleClick(e){
this.props.roomStore.room = e.target.closest('.btn__toggle').querySelector('.btn__headline').innerHTML;
}
This is where I want to get the room
loadRooms(){
if(this.state.isLoaded){
var locations = this.state.things.filter( function (e){
return e.location == this.props.roomStore.room}); //<- this is the relevant variable
const habitems = locations.map((i, key) =>
<div className="btn__toggle" key={i.UID} type="submit">
<div className="btn__headline">{i.label}</div>
</div>
)
return habitems;
}
}
And this is where I render my Items:
render() {
if(this.state.isLoaded){
return (
<div>
<h1 id="h1">{this.props.roomStore.room}</h1>
<div className="btn__wrapper">{this.loadRooms()}</div>
</div>
);
}
I assume it might not work, because the variable gets set in the other component before you actually open the right one, that uses it in render, so the whole component gets rendered before even mounted.
But I might be wrong on that. Any help would be much appreciated.
Errors that occur are:
index.module.js:860 Uncaught TypeError: Cannot read property 'props' of undefined
The above error occurred in the component
Uncaught (in promise) TypeError: Cannot read property 'props' of undefined
react-dom.development.js:506 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
The problem you have is that your filter function has no access to this, leading to the error Cannot read property 'props' of undefined. You can filter out your roomStore from your props using a destructuring assignment beforehand and use it instead of accessing this.props.
loadRooms() {
const { roomStore } = this.props;
if (this.state.isLoaded) {
var locations = this.state.things.filter( function (e){
return e.location == roomStore.room
});
/* ... */
}
}
The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

how to use watch function in vue js

could you please tell me how to use watch function in vue js .I tried to used but I got this error.
vue.js:485 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "m"
found in
---> <AddTodo>
<Root>
https://plnkr.co/edit/hVQKk3Wl9DF3aNx0hs88?p=preview
I created different components and watch properties in the main component
var AddTODO = Vue.extend({
template: '#add-todo',
props: ['m'],
data: function () {
return {
message: ''
}
},
methods: {
addTodo: function () {
console.log(this.message)
console.log(this.m);
this.m =this.message;
},
},
});
When I try to add item I am getting this error.
Step to reproduce this bug
Type anything on input field and click on Add button
this.m =this.message;
this line is the issue,
It's recommended that you don't modify prop directly...
instead create a data property and then modify it.
It shows warning because you're modifying the prop item, prop value will be overwritten whenever the parent component re-renders.
The component's props are automatically updated in the component as soon as you change their value outside of it.
For this reason, trying to change the value of a property from inside your component is a bad idea: you should use the props as read-only.
If you want to use a prop as the initial value of some of your component's data you can simply declare it this way:
data: function () {
return {
changeable: this.receivedProp;
}
},
That being said, if you are trying to change the value of a prop from inside a component to be able to use your reassigned prop outside of it, you are doing it the wrong way. The way you should handle this is by using Vue's custom events.
Remember, as Vue's documentation states:
In Vue, the parent-child component relationship can be summarized as props down, events up. The parent passes data down to the child via props, and the child sends messages to the parent via events.

How the props of react.js are declared

I'm new to React. I'm not understanding a part in this code:
var HelloMessage = React.createClass({
render: function() {
return <h2>{this.props.message}</h2>;
}
});
var TextBox = React.createClass({
getInitialState: function() {
return { isEditing: false }
},
update: function() {
// Where is props.update defined? //
this.props.update(this.refs.messageTextBox.value);
this.setState(
{
isEditing: false
});
},
edit: function() {
this.setState({ isEditing: true});
},
In the code I can't find the props declaration for update. But looking through the code we should see "update" as a property of the TextBox component.
I'm not seeing an explicit declaration of this.props.update within any render method.
How/Where is props.update defined?
So inside the HelloReact component render method, a few TextBox components are returned like so:
...
<TextBox label='First Name' update={this.update.bind(null, 'firstName')}>
...
Now here what is happening is that HelloReact is passing a prop named update to this TextBox component. This means that inside the TextBox component I will be able to use this prop with this.props.update. Every prop that is passed down from the parent will populate this.props of the child. In this specific case we are passing down label and update.
Now inside the TextBox component we will be able to access these props intuitively with this.props.label and this.props.update. Inside this component it's define a private method that is called update, this is the code from the snippet you posted with better formatting:
...
update: function() {
this.props.update(this.refs.messageTextBox.value);
this.setState({ isEditing: false });
},
...
So here we are calling this.props.update which is the prop that was passed down from the parent in HelloReact. The reason we are wrapping this call in a private method is because on top of being able to call this.props.update() we also want to do something else, in this case we want to update the state of the TextBox component as well.
I hope this explanation was clear enough. I suggest reading about React from the official docs which are pretty amazing, or watch any of the many tutorials online. These are key concepts of React and you need to understand them properly in order to be able to develop in React.
For this case you might wanna read this, which comes from the offical docs and is about props.

Should I wrap all React render code with try{} catch(err){}?

Sometimes React fails silently when running render code. It's then hard to find out where it broke.
I wonder, if I should just put all the code for render function inside try {} catch(err) {alert(err)}?
Is it a good practice or should I catch and debug errors in a different way?
One of the cases it shows no errors is when I send some props variables to a component which are actually undefined and it tries to get properties of that undefined variable, like this:
<FormField form={this.props.form} />
Then, inside FormField component render function there is this code:
var value = this.props.form[this.props.id]
Now, if form prop is undefined, the code in FormField component doesn't show any error, but when I use try/catch, it shows this:
Probably I should use try/catch to debug the errors then fix and add checks, then remove try/catch for production?
Sounds like you could benefit from prop validation. Then you can decide upon types for your props.
React.createClass({
propTypes: {
form: React.PropTypes.object,
id: React.PropTypes.string
}
// ...
})
Then if you don't supply a property of the correct type, it will log an error.
Alternatively, you could supply a default value for the property if that would be more appropriate.
React.createClass({
getDefaultProps: function() {
return {
form: defaultFormProp
};
}
});
Then if you don't supply the prop when you render the component, the default value will be used.

in a react component, how to get `this` in static function?

attempting to create a static function within a react component. the function uses this to get its data, but this is out of scope when the function is called.
here is a very simple example:
var Test = React.createClass({
val: 5,
statics: {
getVal: function() { return this.val }
},
render: return( <div>{this.val}</div> )
});
Test.getVal(); => undefined!!
obviously this has lost its scope when Test.getVal() is called. how to get this inside the getVal() function?
fyi, the following standard javascript parent approach does not work:
Test.getVal.apply( Test ); => undefined
Check out the docs on statics.
Whatever you put in statics is not going to have the context of an actual React component instance, but the val property you're defining is a property of an actual React component instance. It's not going to exist before you actually render the component, because that's when all the non-static properties are constructed. Statics are supposed to be component-related functions that are usable outside the context of an actual instance, just like for example static functions in C# and many other languages.
It simply doesn't seem to make sense to want to access a React component instance from a statics function. Maybe you need to think over what you're actually trying to achieve. If you really want to be able to access a specific component's properties, then I guess you can pass the instance as an argument to the static function, but then of course that would be usable once you have actually constructed a component.
Ahh ok misunderstanding. If you need to somehow be able to call this method whenever then your val must be located in statics as well but your render function would then have to reference Test.val instead of this.val. If this isn't a requirement though it would be best to stick to props/state and accessing things from within the component since the component will not autoupdate based on changes to the val.
var Test = React.createClass({
statics: {
val: 5,
getVal: function() {
return this.val
}
},
render: function(){
return( <div>{Test.val}</div> )
}
});
console.log('VAL IS' , Test.getVal());
Link to fiddle with example https://jsfiddle.net/dgoks3Lo/

Categories