I am working with this flask react template project here and I am running into an issue
https://github.com/bonniee/react-flask
When rendering index.html, I want to pass back some data from flask
#app.route('/')
def hello_world():
return render_template('index.html', somedata="YOOOO")
And use it in the react components
render() {
this.loadDataFromServer();
return <h1>sup? {{somedata}}</h1>;
}
});
Is there a clean way to do it in this project format?
In your template, you could include a script tag that sets window.somedata to the value you want. You could then access that directly in render, or preferably if you've got flux or redux you could dispatch an action with that data during mounting of the react components.
Related
I need help with this problem. My objective is to put a website inside a ReactJs web app. I tried using the iframe of ReactJs, it does not work.
Is there a way to use React Native WebView component inside a ReactJs web app?
Or is there a Webview Component in ReactJs
I do want the end-user to jump to another tab in order to use the website. I want them to continue to stay in the ReactJs web app and use the website.
The website that I am putting is a .Net website and I am doing a ReactJs project, not a React Native Project
simply using iframe should work as this exemple (source below)
since your giving an url to this iframe langage doesn't matter if it can be served in http(s)
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
render() {
return <iframe src="https://<website>/" />;
}
}
ReactDOM.render(<App />, document.getElementById("container"));
As said in source the src url should be embeddable to be used inside an iframe if not you can use a reverse proxy to serve this url and change headers
source:
https://blog.bitsrc.io/best-practices-in-using-iframes-with-react-6193feaa1e08
I am building an application using angular and redux (ngRedux). Now i want to use react instead of angular for improvement in performance. It is a huge application so it is not possible to build it from scratch. So i want to use the routing of angularJS (angular-ui-router) and as any "abc" state become active then the react component become load and this react component should use the pure redux against every single event.
How can i maintain my application accordingly that a single module is build in react-redux and connected to angular only through routing state. Keep in mind that the other modules of application should also not be disturbed.
Well to render React components into Angular is quite easy. But I just assume you use directiveor component from angular already.
So in the case of directive you could skip the whole templating "none sense" and let React handle that for you
module.directive("reactTest",function() {
return {
link:function(scope,element,attr) {
class App extends React.Component {
constructor(props) { super(props) }
render <div></div>
}
element.replace(App);
}
}
});
So this how you would get React into Angular. Redux ist basically the same. You simple use the connect function of redux and off you go.
I am using react for creating a sample page which has server side rendering using renderToString() for SEO friendly pages.
this is my server.js code
app.get('*', (req, res) => {
match(
{ routes, location: req.url },
(err, redirectLocation, renderProps) => {
// in case of error display the error message
if (err) {
return res.status(500).send(err.message);
}
// generate the React markup for the current route
let markup;
if (renderProps) {
markup = renderToString(<RouterContext{...renderProps}/>);
} else {
res.status(404);
}
// render the index template with the embedded React markup
return res.render('index', { markup });
}
);
});
My page is search page which is static initially and when the user enters the input it fetches data from backend and renders a list of components in the same page.
When I see view page source in browser, I can see only the initial static content, not the html of list which renders after the backend response.
What is the right method to get the updated HTML when the component state changes.
You still need to include your component, and React itself, on your clientside and call React.render on the same base element in the DOM.
Simply serving the result of React.renderToString as static HTML does will only do exactly that, serve static html.
If you want your component to get mounted properly on the clientside so it can react to clientside events and re-render for state changes, you'll need to mount it on the static html, this is done by calling React.render on page load on the clientside.
There's more about this here: https://strongloop.com/strongblog/node-js-react-isomorphic-javascript-why-it-matters/
Save the fetched data to your state and the component will re-render itself. That way your view will render the new content when it's fetched from the backend.
In current setup, I'm building multi-page universal web application (using react-router to do routing on both server and client). This project doesn't use any (redux) store (which I consider unneccessary for now).
One of component responsible for fetch data from remote API, done inside componentWillMount method.
When render on server, the component will fetch data, do rendering and send rendered HTML to client.
When client mount HTML with ReactJS, it fetch data once again from componentWillMount method. That's cause unneccessary double data fetch.
Does it have any solution?
Thanks for answer from Dominic Tobias.
I tried develop a couple solution but I found one that suitable for me.
First, I decided not to fetch data either in componentWillMount or componentDidMount inside component, but create a static method call fetchData which return Promise like this:
class PageContainer extends Component {
static fetchData(params) {
return fetch('...URL...')
}
render() {
const {data} = this.props;
//render logic here
}
}
and on server side, call PageContainer.fetchData and wait until promise is fulfilled, pass data as props to PageContainer and render HTML with hydrated data like this
<html>
<head></head>
<body>
<div id="roor">{..react rendered HTML..}</div>
<script>window.__DATA__ = {..data..}</script>
</body>
</html>
like I said, for this app, I think that redux is unnecessary for now.
Then, there is a problem on client side routing which is react-router cannot load async data. To fix that, I went looking for AsyncProps and write my own tiny version of that, called AsyncComp. You can bootstrap React on client side with react-router like this:
const Root = <Router history={browserHistory} routes={routes} render={(props) => <AsyncComp {...props} data={window.__DATA__}/>}/>
ReactDOM.render(Root, document.getElementById("root"));
That's all.
PS. After I built AsyncComp, it can also be used on server side like this:
AsyncComp.fetchData(routerProps)
.then((data) => {
const html = ReactDOM.renderToString(<AsyncComp {...routerProps} data={data}/>)
res.render('index', { html: html, data: data })
})
Since your data already exists you should have a function which will make a conditional fetch which you can call on both the server and componentDidMount (you're not supposed to make ajax calls in componentWillMount).
For example this is how a component looks for me using redux:
class User extends Component {
static readyOnActions(dispatch, params) {
return Promise.all([
dispatch(UserActions.fetchUserIfNeeded(params.id))
]);
}
componentDidMount() {
User.readyOnActions(this.props.dispatch, this.props.params);
}
If this is the current page then the server will call the readyOnActions, and on the client componentDidMount can call the same thing - the action called fetchUserIfNeeded will only make an AJAX request if the server hasn't already done it by checking if the data already exists (and you can add further checks such as if it's valid, if it's not already fetching etc).
I am trying to mount a react component using jquery to a bootstrap modal body and then open the modal after a successful ajax request, however I cannot seem to get the react component to load. This is what I have so far:
After success I am calling the assignModal function, I am inside a parent react component.
assignModal: function(){
$('.assign-modal-body').html(<Cortex.VulnerabilityList.AssignModal parent={this}/>);
$("#vuln-assign-modal").modal('show');}
And here is the react component
Cortex.VulnerabilityList.AssignModal = React.createClass({
componentDidMount: function() {
console.log("Component mounted")
},
render: function() {
return (
<h1>Hello</h1>
)
}
});
From my experience, you're going to have trouble if you try to use both jQuery and React to manipulate the DOM. If it's at all an option for you, get rid of jQuery and fully embrace React's declarative programming paradigm.
But maybe you have jQuery widgets you want to use. In that case, try and design your app in such a way that jQuery never writes to the DOM within your React tree.
So a few options:
Use jQuery and React, but separately - Have your React app descending from some root <div> and have your modal in a sibling <div>. Then just use jQuery and normal HTML to render your modal without involving React.
Stop using jQuery - Use React to manage your modal. So instead of responding to assignModal by setting the innerHTML of a DOM element with jQuery, simply set some global state to showModal = true and in the render method of the modal if (!showModal) return null or something like that. I wrote a post about this recently.