Reputation: 27266
There's a number of posts in SO related to not being able to update props in ReactJS. E.g. this one.
In the referenced post the explanation is given that this is part of the ReactJS philosophy, helps in debugging, etc. Also this answer (in the same thread) shows how it's done inside ReactJS (by using Object.freeze
).
I am ReactJS newbie and so put together this small example to try to see what happens when one attempts to modify props (also in jsfiddle)
<!doctype html>
<html>
<body>
<div id='react-app'></div>
<script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react.js"></script>
<script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react-dom.js"></script>
<script type='text/javascript'>
var rce = React.createElement.bind(React);
var TodoList = React.createClass({
propTypes: {
todos: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
},
render: function() {
var props = this.props;
var todos = this.props.todos;
var self = this;
return rce('div', {}
,rce('ul', {}
, (function(){
return todos.map(function(x, i) {
return rce('li', {key: i}, x);
});})())
,rce('button', {onClick: function() {
// delete props.todos; // fails
// props.todos = []; // fails
todos.splice(0, todos.length); // succeeds
console.log(todos);
self.forceUpdate();
}}, 'clear all'));
}
});
var todoList = rce(TodoList, {todos: ['walk dog', 'feed cat', 'water flowers']});
ReactDOM.render(todoList, document.getElementById('react-app'));
</script>
</body>
</html>
I am sure the above code violates many good practices but it's apparently easy to modify props
. I understand this is because Object.freeze
is called on the props
object and not on its properties as well and so as it is, it does not "freeze" against splicing (or changing a props' object's attribute values). My questions are:
Upvotes: 0
Views: 173
Reputation: 2044
According to react
philosophy, you are advised not to edit the props because it is not how react
is design (Thinking in React).
You should use the state
of your view which conforms to changes and you may pass some data from state
to props
.
see the correct example of your code:
var TodoList = React.createClass({
propTypes: {
todos: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
onSomeAction: React.PropTypes.func.isRequired
},
render: function() {
var todos = this.props.todos;
var self = this;
return rce('div', {}
,rce('ul', {}
, (function(){
return todos.map(function(x, i) {
return rce('li', {key: i}, x);
});})())
,rce('button', {onClick: this.props.onSomeAction});
}
});
The logic of what to do and how, when the button is clicked, should be place in the view's owner, unless you manage you own state in the current view.
Also,
There is a concept which defines dummy views and smart views.
in short, dummy views are such that they only get properties and shows some data on screen, but they do not interact with other objects or able to change the view's state
.
However, smart views are such that they are interacts with others, responding to events and etc. as well as able to change their state and pass any other data to its children.
Hope its clearer for you now...
Upvotes: 1