Pass updated data to root component - reactjs

here is my code :
var data = "hello";
var RootComponent = React.createClass({
render: function() {
return (
<p className="root">
{this.props.data}
</p>
);
}
});
React.renderComponent(
<RootComponent data="data" />,
document.getElementById('content')
);
I want to change the value of data(initially hello), so the page is refreshed with the new data value. But the function that change data is not in React, and I can't find a way to "plug" them. Any idea how to do so?
Thanks.

Listen on the change and call React.renderComponent() as mentioned by Felix. Per React's documentation:
Render a React component into the DOM in the supplied container and return a reference to the component.
If the React component was previously rendered into container, this
will perform an update on it and only mutate the DOM as necessary to
reflect the latest React component.
If the optional callback is provided, it will be executed after the
component is rendered or updated.
If you have the ability to look into using Flux Stores for your model layer I would strongly encourage you to do so.

Related

How to render component from variable and save props and context?

I'm creating several React Components that behave in the same way except of rendering data. I put similar logic into mixin, including render function. The only thing I pass is the additional component that is responsible for presenting data in required way.
var A = React.createClass({
mixins: [MyMixin],
MyComponent: B,
});
var B = React.createClass({
get_value: function() {
// should return some value using top-level context
},
render: function() {
var x = this.get_value()
}
})
MyMixin = {
// some logic
render: function() {
<div>
// some common markup
<this.MyComponent
// some props
/>
</div>
}
}
The problem here is that component B (which is rendered through variable in mixin) doesn't have top-level context, from parents. At the same time components in the 'common markup' block does have it. How could I render components in the way above and save top-level context?
You can't access the top level context because B is not inheriting or sharing anything with A. Your mixin is just a simple extension of shared functionality and you just render component defined in component A. There is nothing that binds A and B.
What you could do is pass the needed stuff in the props of B.
<div>
// some common markup
<this.MyComponent
parentProps={this.props}
parentState={this.state}
/>
</div>
What you really should do is add all the common code in the mixin and use that mixin in both of your components. Since render is NOT common for your components you should define the render in each component or make an other mixin for that purpose.

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 access new props.value before render function in React life cycle

All:
If I define a component have a property called "value",
var Child = React.createClass({
componentWillReceiveProps: function(){
console.log("componentWillReceiveProps",this.props.value);
},
shouldComponentUpdate : function(){
console.log("shouldComponentUpdate", this.props.value);
return true;
},
componentWillUpdate : function(){
console.log("componentWillUpdate", this.props.value);
},
componentDidUpdate: function(){
console.log("componentDidUpdate", this.props.value);
},
render: function(){
return (
<div>The value generated by Parent: {this.props.value}</div>
);
}
});
If I want to give the newly set props.value to state.value( or maybe prepare a value for transition/interpolation ), but all stages before render only have previous value. Could anyone show me how to get new value before render?
Thanks
Important Note: componentWillReceiveProps is deprecated: https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops
componentWillReceiveProps is called when a component receives new props.
From here you can update the component's state using setState without triggering a render.
You can access the new props from the first argument passed to
componentWillReceiveProps
You can access the old props this.props
From your example:
componentWillReceiveProps: function(nextProps){
console.log("componentWillReceiveProps", nextProps.value, this.props.value);
},
JSBin demo
For anybody finding this old question via Google, it's out of date. You shouldn't be using this function anymore and, moreover, there are other solutions that don't involve updating the state! Take a look at this react.js blog article, You Probably Don't Need Derived State.
It's not totally clear what OP wanted to do but there are various appropriate solutions in that article. In my case, I wanted to reset a popup window, when a different element was clicked. You can do this with the key attribute. It works like magic. :)

Difference between ReactClass and ReactComponent?

In the React Dom Terminology, what is the difference between ReactClass and ReactComponent?
Simply put:
ReactClass: A model or a shape for components, if you want to create a component called DatePicker, the shape is the ReactClass, not each of the individual components/instances will you create based on that shape.
var MyComponent = React.createClass({
render: function() {
...
}
});
ReactComponent or ReactElement: A component instance that you create based on a pre-defined ReactClass. If you create a component called DatePicker, each instance of that component that is rendered is a ReactElement
var component = React.createElement(MyComponent, props);
Normally you don't use React.createElement because you can just use something like this <MyComponent />, but it's really useful if you want to dynamically create instances of components, like for storing in a variable and rendering them later.
I just found it from my link.
I keep this question for someone who may have the same question.
From React Components,
A ReactComponent Class is simply just a JavaScript class (or "constructor function").
var MyComponent = React.createClass({
render: function() {
...
}
});
When this constructor is invoked it is expected to return an object with at least a render method on it. This object is referred to as a ReactComponent.
var component = new MyComponent(props); // never do this

Setting the initial state in React components for progressive enhancement & Flux architecture

I've read on http://scotch.io/tutorials/javascript/build-a-real-time-twitter-stream-with-node-and-react-js and it describes a technique of taking over server rendered React components seamlessly:
Server renders into {{{markup}}} in handlebars, and pass initial state.
<section id="react-app">{{{ markup }}}</div>
<script id="initial-state" type="application/json">{{{state}}}</script>
Then on the client side javascript
/** #jsx React.DOM */
var React = require('react');
var TweetsApp = require('./components/TweetsApp.react');
// Snag the initial state that was passed from the server side
var initialState = JSON.parse(document.getElementById('initial-state').innerHTML)
// Render the components, picking up where react left off on the server
React.renderComponent(
<TweetsApp tweets={initialState}/>,
document.getElementById('react-app')
);
But in a flux architecture, such as described in this article http://scotch.io/tutorials/javascript/creating-a-simple-shopping-cart-with-react-js-and-flux, state is initialized in the getInitialState lifecycle method:
// Method to retrieve state from Stores
function getCartState() {
return {
product: ProductStore.getProduct(),
selectedProduct: ProductStore.getSelected(),
cartItems: CartStore.getCartItems(),
cartCount: CartStore.getCartCount(),
cartTotal: CartStore.getCartTotal(),
cartVisible: CartStore.getCartVisible()
};
}
// Define main Controller View
var FluxCartApp = React.createClass({
// Get initial state from stores
getInitialState: function() {
return getCartState();
},
// Add change listeners to stores
componentDidMount: function() {
ProductStore.addChangeListener(this._onChange);
CartStore.addChangeListener(this._onChange);
},
// Remove change listers from stores
componentWillUnmount: function() {
ProductStore.removeChangeListener(this._onChange);
CartStore.removeChangeListener(this._onChange);
},
// Render our child components, passing state via props
render: function() {
return (
<div className="flux-cart-app">
<FluxCart products={this.state.cartItems} count={this.state.cartCount} total={this.state.cartTotal} visible={this.state.cartVisible} />
<FluxProduct product={this.state.product} cartitems={this.state.cartItems} selected={this.state.selectedProduct} />
</div>
);
},
// Method to setState based upon Store changes
_onChange: function() {
this.setState(getCartState());
}
});
module.exports = FluxCartApp;
Which one is the right approach to setting state from a progressive enhancement point of view?
Thinking about progressive enhancement I like how flux and react work together.
I am using ReactJS and Flux in my current project and everything is clean and easy. All you have to be aware of is showing some discipline of creating new stores when it really is needed. I dont really like the eventEmitter stuff though. I just trigger my own events which I define in a seperate eventConstants.js file this allows me to have several components listening for different changes on the same store.
This really scales well.
Answering your question:
It does depend about your usecase. Ignoring that rendering an initial page on the server is great for SEO it does only make sence to render on the server if users should all see pretty much the same content. I like to keep client stuff on the client.
I hope this helped you

Resources