
Security News
How Enterprise Security Is Adapting to AI-Accelerated Threats
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.
@dws/muster-react
Advanced tools
Muster-React is a library that helps using Muster in an application written in React.
npm install --save @dws/muster-react
Muster-React exposes a [[container]] function which is used for creating a wrapper for a
React component. This wrapper component is responsible for making queries to Muster, handling
responses and passing them as props to the wrapped component. The wrapper component assumes the
existence of a muster property on a React context. It can be set with the help of a [[Provider]]
component. The library exports a modified version of a muster helper. By default, when using
muster from @dws/muster it creates an application with all core muster graph nodes. This custom
version of muster helper additionally includes all muster-react graph nodes.
import * as React from 'react';
import muster, { Provider } from '@dws/muster-react';
// Create a muster app
const app = muster({
name: 'Bob',
});
function Application() {
return (
<Provider muster={app}>
{/* Your application goes here */}
</Provider>
);
}
This example shows how to create a Muster application that has a single branch name.
The Application component is responsible for storing that application on the React context so
that any child component has access to it.
import * as React from 'react';
import { container } from '@dws/muster-react';
function MyComponent({ name }) {
return <h1>{name}</h1>;
}
const MyConnectedComponent = container({
graph: {
name: 'Bob',
},
props: {
name: true,
},
})(MyComponent);
// To render this component simply type <MyConnectedComponent />
// No props are needed as they'll be injected by Muster-React
This example shows how to create a very basic Muster-React component. We first start by creating
a pure React component that takes one prop name. Next we create a connected component out of it.
When creating a Muster application we do this by defining a Muster graph with nodes and
relationships between them. Muster-React connects that global graph through the [[Provider]]
discussed in the previous example. The global graph contains the state of the application and it is
shared between all of the connected components. Additionally, each component has its own,
local graph. This graph is unique to every instance of a given component - one component does
not have access to another component's local graph. In this example, the configuration of the
connected component is split into two parts:
ref(global('nested', 'global', 'path'))In this example we used a short-hand [[getter]] notation - name: true. This means we simply want
to get the value of the name node. Internally Muster-React prepares a query that looks like this:
import { key, query, root } from '@dws/muster';
const myConnectedComponentQuery = query(root(), {
name: key('name'),
});
The connected component runs that query against the local graph and subscribes to the result
when its componentWillMount method get called by React. The subscription is closed when the
componentWillUnmount method gets called by React.
import * as React from 'react';
import muster, { container, global, Provider, ref } from '@dws/muster-react';
function User({ name }) {
return <h1>{name}</h1>
}
const ConnectedUser = container({
graph: {
name: ref(global('user', 'name')),
},
props: {
name: true,
},
})(User);
const app = muster({
user: {
name: 'Bob',
},
});
function Application() {
return (
<Provider muster={app}>
<ConnectedUser />
</Provider>
);
}
This example shows how to make references to the global muster graph.
import * as React from 'react';
import { container, propTypes, types, variable } from '@dws/muster-react';
function NewsletterSettings({ sendNewsletter, setSendNewsletter }) {
return (
<button onClick={() => setSendNewsletter(!sendNewsletter)}>
{sendNewsletter ? 'Stop sending newsletter' : 'Subscribe to newsletter'}
</button>
);
}
const ConnectedNewsletterSettings = container({
graph: {
sendNewsletter: variable(false),
},
props: {
sendNewsletter: types.bool,
setSendNewsletter: propTypes.setter('sendNewsletter', types.bool),
},
})(NewsletterSettings);
This example shows how to declare setter props and how to use them. This example also introduces the
concept of typed props. In previous example we've been defining props as propName: true which is
a short-hand of propName: types.any. In this example we defined the type of the prop explicitly:
sendNewsletter: types.bool. This will inform Muster to validate the type of the property as bool.
Next we're defining a setSendNewsletter property, which is a setter of a sendNewsletter node
and that it should be validated as a setter of a boolean values.
In this example we're completely ignoring the return value of the setSendNewsletter setter
function but it's important to remember that it is returning a Promise that resolves to a value
that was set.
import * as React from 'react';
import { action, container, propTypes } from '@dws/muster-react';
function Something({ getGreeting }) {
async function onClick() {
const greeting = await getGreeting('Bob');
console.log(greeting); // Hello, Bob
}
return (
<button onClick={onClick}>Log greeting</button>
);
}
const ConnectedSomething = container({
graph: {
getGreeting: action((name) => `Hello, ${name}`),
},
props: {
getGreeting: propTypes.caller(),
},
})(Something);
This example shows how to declare an action, get a caller for it and call it. It is similar to
the previous example with setter in a way that the getGreeting caller function returns a
promise, just like the setter function in a previous example.
import * as React from 'react';
import { container, types } from '@dws/muster-react';
function MyComponent({ name }) {
// Display the name
return null;
}
const MyConnectedComponent = container({
graph: {
name: 'Bob',
},
props: {
name: types.string,
},
})(MyComponent);
This example shows how to use Muster types to declare a type of a prop that should be injected to the component.
import * as React from 'react';
import { container, propTypes, types } from '@dws/muster-react';
function MyComponent({ myName }) {
// Display the name
return null;
}
const MyConnectedComponent = container({
graph: {
firstName: 'Bob',
},
props: {
myName: propTypes.getter('firstName', types.string),
},
})(MyComponent);
This example shows how to use the [[getter]] prop type to retrieve a node with a different name than the name used for the prop.
import * as React from 'react';
import { container } from '@dws/muster-react';
function MyComponent({ user }) {
// Display the user
return null;
}
const MyConnectedComponent = container({
graph: {
user: {
firstName: 'Bob',
lastName: 'Doe',
address: {
line1: '1141 Losbi Lane',
postCode: 'A0Y 6D3',
},
},
},
props: {
user: {
firstName: true,
lastName: true,
address: {
line1: true,
},
},
},
})(MyComponent);
This example shows how to request a nested data from local graph. By now you've noticed that the
shape of the props must match the shape of the graph. You might have also noticed that the address
in the local graph defines a postCode node but the props are not requesting it. This shows
that you don't have to load everything from your local graph to the component props.
import * as React from 'react';
import muster, { container, global, Provider, ref } from '@dws/muster-react';
const app = muster({
currentUser: {
firstName: 'Bob',
lastName: 'Doe',
address: {
line1: '1141 Losbi Lane',
postCode: 'A0Y 6D3',
},
},
});
function MyComponent({ firstName, lastName, address }) {
// Display the user
return null;
}
const MyConnectedComponent = container({
graph: ref(global('currentUser')),
props: {
firstName: true,
lastName: true,
address: {
line1: true,
},
},
})(MyComponent);
function Application() {
return (
<Provider muster={app}>
<MyConnectedComponent />
</Provider>
);
}
In the example Referencing global graph we showed that nodes from the local graph can reference
parts of the global graph. This example extends that concept by showing that the entire local graph
can point to a specific part of a global graph. This means that every prop must match branch names
from the currentUser in the global graph.
import * as React from 'react';
import { container, propTypes } from '@dws/muster-react';
function MyComponent({ numbers }) {
// Display the numbers.
// In this example numbers = [1, 2, 3, 4]
return null;
}
const MyConnectedComponent = container({
graph: {
numbers: [1, 2, 3, 4],
},
props: {
numbers: propTypes.list(),
},
})(MyComponent);
This example shows how to use the [[list]] prop type to retrieve items from a collection.
import * as React from 'react';
import { container, propTypes } from '@dws/muster-react';
function MyComponent({ friends }) {
// Display the list of friends
// In this example friends = [
// { firstName: 'Sylvia', lastName: 'Garcia' },
// { firstName: 'Carl', lastName: 'Francis' },
// { firstName: 'Arthur', lastName: 'Kennedy' },
// ]
return null;
}
const MyConnectedComponent = container({
graph: {
friends: [
{ firstName: 'Sylvia', lastName: 'Garcia', age: 48 },
{ firstName: 'Carl', lastName: 'Francis', age: 63 },
{ firstName: 'Arthur', lastName: 'Kennedy', age: 28 },
],
},
props: {
friends: propTypes.list({
firstName: true,
lastName: true,
}),
},
})(MyComponent);
This example shows how to use the [[list]] prop type to retrieve items with specific properties from
a collection. In this case we omitted the age property as it wasn't necessary for our component.
In Muster there's no difference between loading synchronously available data and asynchronous. Queries run against Muster graph are waiting for the entire data-set to be loaded before returning it to the subscribers.
import * as React from 'react';
import { container, fromPromise } '@dws/muster-react';
function MyComponent(props) {
console.log('Rendering the component: ', props);
return null;
}
const MyConnectedComponent = container({
graph: {
async: fromPromise(() => Promise.resolve('value')),
sync: 'value',
},
props: {
async: true,
sync: true,
},
})(MyComponent);
// Console output (when rendered):
// Rendering the component: { async: 'value', sync: 'value' }
This example shows that the rendering happens only when all of the data is loaded. This prevents inconsistent UI states and ensures the minimum amount of renders.
There are sometimes moments when you would like to show a loading spinner when some data is loading as it might take longer time to retrieve it from the server. Muster-React introduces two prop types doing just that: [[defer]] and [[isLoading]].
The [[defer]] prop can be applied to any [[getter]] and [[list]] prop, and it instructs Muster to
load the given node asynchronously. When the node does not resolve immediately for the first time
it will return a fallback value: null. However, when the node was resolved and goes to the
pending state again this prop will return a previous value of this node as a fallback.
The [[isLoading]] prop is a meta-property which takes a name of a different prop from the same
branch (it must be a prop wrapped in a [[defer]]) and monitors the pending state of it.
import * as React from 'react';
import { container, fromPromise, propTypes } '@dws/muster-react';
function MyComponent(props) {
console.log('Rendering the component: ', props);
return null;
}
const MyConnectedComponent = container({
graph: {
async: fromPromise(() => Promise.resolve('value')),
sync: 'value',
},
props: {
async: propTypes.defer(true),
isLoadingAsync: propTypes.isLoading('async'), // It isn't necessary for the defer to work as described
sync: true,
// isLoadingSync: propTypes.isLoading('sync'), // ERROR, sync is not deferred!
},
})(MyComponent);
// Console output (when rendered):
// Rendering the component: { async: null, isLoadingAsync: true, sync: 'value' }
// Rendering the component: { async: 'value', isLoadingAsync: false, sync: 'value' }
This example shows how to defer loading certain parts of the graph. One thing to remember is that for this to work correctly, every asynchronous prop must be wrapped in defer. This is due to the fact, that Muster normally waits for all data to be loaded before returning it to subscriber. The [[defer]] prop is notifying Muster that a particular graph node is not crucial for the application to work and the query doesn't have to wait for it to resolve. When some other nodes in the query share the same async behaviour but aren't wrapped in [[defer]] they will be blocking the query from resolving. The following example shows how that might happen:
import * as React from 'react';
import { container, fromPromise, propTypes } '@dws/muster-react';
function MyComponent(props) {
console.log('Rendering the component: ', props);
return null;
}
const MyConnectedComponent = container({
graph: {
async1: fromPromise(() => Promise.resolve('value 1')),
async2: fromPromise(() => Promise.resolve('value 2')),
sync: 'value',
},
props: {
async1: propTypes.defer(true),
async2: true,
sync: true,
},
})(MyComponent);
// Console output (when rendered):
// Rendering the component: { async1: 'value 1', async2: 'value 2', sync: 'value' }
The component is rendered only once, because the async2 prop is not marked as deferred.
So far we've covered how to handle loading non-crucial data. It's not always possible to render
a component without certain points of data. For these cases you can use a special property
of [[container]] - renderLoading. It takes a function which will be called whenever a
component goes into a loading state - data is pending but not marked as deferred. The function
takes one parameter: last props, and is expected to return a JSX Element to render. You can use
this function to render for example a loading spinner.
import * as React from 'react';
import { container, fromPromise } '@dws/muster-react';
function MyComponent(props) {
console.log('Rendering the component: ', props);
return null;
}
const MyConnectedComponent = container({
graph: {
async: fromPromise(() => Promise.resolve('value')),
sync: 'value',
},
props: {
async: true,
sync: true,
},
renderLoading: (props) => {
console.log('Rendering a loading spinner');
return null;
},
})(MyComponent);
// Console output (when rendered):
// Rendering a loading spinner
// Rendering the component: { async: 'value', sync: 'value' }
Error handling is as very important part of application development. Sometimes it's the network problem, a simple developer mistake, or user trying to do something incorrectly. Good applications should be able to recover from these kinds of issues. Muster and Muster-React enable a few layers of error handling:
transformResponseMiddleware and handleErrors helperIfErrorNoderenderError function.The first two methods of error handling are covered in Muster documentation. This example will
focus only on the last one - renderError.
import * as React from 'react';
import { container, computed } '@dws/muster-react';
function MyComponent(props) {
console.log('Rendering the component: ', props);
return null;
}
const MyConnectedComponent = container({
graph: {
name: computed([], () => {
throw new Error('Some unexpected error');
}),
},
props: {
name: true,
},
renderError: (errors, props) => {
console.log('An error has occurred: ', errors);
return null;
},
})(MyComponent);
// Console output (when rendered):
// An error has occurred: [
// { $type: 'error', error: new Error('Some unexpected error'), path: ['name'] },
// ]
This example shows how to use the renderError method to access the array of errors.
As mentioned at the beginning of this document, the connected component does not require any react props to run correctly. That doesn't mean it can't have any props. Any additional props set on a connected component can be accessed from the local graph with the help of a [[PropNode]]. This example shows how to access such props:
import * as React from 'react';
import { container, computed, prop } from '@dws/muster-react';
function MyComponent({ greeting }) {
console.log('Greeting: ', greeting);
return null;
}
const MyConnectedComponent = container({
graph: {
greeting: computed([prop('name')], (name) => `Hello, ${name}`),
},
props: {
greeting: true,
},
})(MyComponent);
// Somewhere in another part of the application:
<MyConnectedComponent name="Bob" />
// Console output (when rendered):
// Greeting: Hello, Bob
FAQs
Muster React view framework integration
The npm package @dws/muster-react receives a total of 6 weekly downloads. As such, @dws/muster-react popularity was classified as not popular.
We found that @dws/muster-react 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
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.