
Security News
vlt Launches "reproduce": A New Tool Challenging the Limits of Package Provenance
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
react-resolver
Advanced tools
Async-rendering & data-fetching for universal React applications.
React Resolver let's you define data requirements per-component and will handle the nested, async rendering on both the server & client for you.
React's rendering is synchronous by design. As a result, rendering on the server is left as an exercise for the rest of the community to figure out.
There are some cludgy solutions for this, most of which require having
fat handlers components controllers at the top of your application
that are responsible for marshalling data for all components under them.
For a non-trivial application, this means mixing concerns between your specialized components and the controllers, which is conceptually difficult and programmatically annoying to maintain.
The simplest example is a pure, client-side only application. Afterwards, we can change a few lines to turn this into a universal application.
If you're the visual type, view the examples:
v0.13
or v0.14
For browsers that don't natively support Promises, use ES6 Promises.
react-resolver
$ npm install --save react-resolver
Suppose you have the following Stargazer
component to render a Github user's
profile:
export default class Stargazer extends React.Component {
static propTypes = {
user: React.PropTypes.object.isRequired,
}
render() {
/* Render profile from this.props.user */
}
}
In 2014, you would use componentWillMount
to fire off an AJAX request for
the profile, then use setState
to trigger a re-render with the data.
This won't work on the server-side, and it's annoying to test.
According to most universal boilerplates, we'd put static fetchData()
function
in our component for a middleware or library to handle, rendering the component
when data comes back.
This only works for fat controllers at the top of your application,
usually defined by a React Router <Route>
.
Instead, let's decorate it:
import { resolve } from "react-resolver";
// Assuming this _is_ from <Route> component matching `/users/ericclemmons`
@resolve("user", function(props) {
return axios
.get(`https://api.github.com/users/${props.params.user}`)
.then((response) => response.data)
;
})
export default class Stargazer extends React.Component {
Or, if ES7 decorators aren't your bag:
class Stargazer extends React.Component {
...
}
export default resolve(Stargazer)("user", function(props) { ... });
Again, if we're only rendering on the client, we can render like normal:
import React from "react";
Router.run(routes, location, (Root) => {
React.render(<Root />, document.getElementById("app"));
});
The End. (Unless you want to see how to build a universal application)
React Resolver handles bootstrapping server-rendered markup via
Resolver.render
:
import { Resolver } from "react-resolver";
Router.run(routes, location, (Root) => {
// To preserver context, you have to pass a render function!
Resolver.render(() => <Root />, document.getElementById("app"));
});
The server will look very familiar to the client-side version. The difference
being, Resolver.resolve
will async render the application, fetch all data, &
return a <Resolved />
component ready for React.render
, as well as the
data
needed to bootstrap the client:
import { Resolver } from "react-resolver";
Router.create({ location, routes }).run((Handler, state) => {
Resolver
.resolve(() => <Handler {...state} />) // Pass a render function for context!
.then(({ Resolved, data }) => {
res.send(`
<!DOCTYPE html>
<html>
<body>
<div id="app">${React.render(<Resolved />)}</div>
<script src="/client.min.js" async defer></script>
<script>
window.__REACT_RESOLVER_PAYLOAD__ = ${JSON.stringify(data)}
</script>
</body>
</html>
`)
})
.catch((error) => res.status(500).send(error)) // Just in case!
;
});
Enjoy writing universal apps with clarity around data requirements!
If you'd like to contribute to this project, all you need to do is clone this project and run:
$ npm install
$ npm test
If you have questions or issues, please open an issue!
FAQs
Async-rendering & data-fetching for universal React applications
The npm package react-resolver receives a total of 2,649 weekly downloads. As such, react-resolver popularity was classified as popular.
We found that react-resolver demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
Research
Security News
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Research
The Socket Research Team discovered a malicious npm package, '@ton-wallet/create', stealing cryptocurrency wallet keys from developers and users in the TON ecosystem.