Skip to main content

Components

LINCD uses React for creating components (though other rendering engines may be added in the future).

Creating LINCD components is not much different from creating React components. Everything related to rendering and life-cycle methods is exactly the same.

The only thing that is different is how it handles data.

Linked to a Shape

LINCD components get linked to a Shape. The shape informs exactly which data the component can expect to receive. This will be Linked Data, and the shape informs the structure of the data in the graph.

Here is two ways you can create a component and link it to a shape:

Functional components

Functional components are the preferred way to create linked components.

The linkedComponent method links a functional React component to a Shape.

Linked Functional Component example:

import {Person} from '../shapes/Person';
export const PersonView = linkedComponent<Person>(Person, ({source, sourceShape}) => {
//source is a NamedNode, and sourceShape is an instance of Person (for the same named node)
let person = sourceShape;
//get the name of the person from the graph through the shape
return <h1>Hello {person.name}!</h1>;
});

//register all functional components at the end of the file
registerPackageModule(module);

Registered by name

Note that LINCD components need to be registered with a name. To register unnamed functional components (like the example above) with their export name, you need this line add the end of the file

registerPackageModule(module);

This will register all the components in that file with their export name.

Alternatively, you can also name the function and the export:

export const PersonView = linkedComponent<Person>(Person, 
function PersonView({source, sourceShape}) {
//..
}
);

Both work fine.

Finally, note that the shape needs to be provided twice, once as a type (<Person>) and once as the first parameter (linkedComponent(Person,..)

Class based components

You can also choose to create class based components.

For this you can extend the helper class LinkedComponentClass and use the @linkedComponentClass decorator, like so:

import {React} from 'react';
import {linkedComponentClass} from '../module';
import {LinkedComponentClass} from 'lincd/lib/utils/LinkedComponentClass';
import {Person} from '../shapes/Person';
@linkedComponentClass(Person)
export class PersonView extends LinkedComponentClass<Person> {
render() {
//typescript knows that person is of type Person
let person = this.props.sourceShape;

//get the name of the person from the graph
return <h1>Hello {person.name}!</h1>;
}
}

Note here that the same shape needs to be provided to the decorator and as a type parameter of LinkedComponentClass

Linked properties

Linked components typically take a single node from the graph as their main data source. That 'source' is the thing that the component visualizes.

The source can be provided using either of two properties:

  • source - as an instance of a Node
  • sourceShape - as an instance of the shape that the component is linked to

For example, if someone wanted to use the PersonView component earlier on this page they could do that as follows:

Using source

If the consumer of PersonView has NamedNode to hand that represents a person in the graph, they would use the source property:

let node = NamedNode.create();
node.set(rdf.type, foaf.Person);
node.set(foaf.name, new Literal('René'));

return <PersonView source={personNode} />;

Using sourceShape

Or, if they rather have an instance of a Person to hand, they could use that with sourceShape:

let person = new Person();
person.name = 'René';

return <PersonView sourceShape={person} />;

Both are available within the component

Importantly, within PersonView, both source and sourceShape will be available if either of them was provided.

const PersonView = linkedComponent<Person>(Person, ({source, sourceShape}) => {
//the URI of the node in the graph that represents a person
console.log(source.uri);
//sourceShape will be a Person, so we can just get the name like this
console.log(sourceShape.name);
//shapes simply wrap a node with extra functionality, so you this is true
console.log(sourceShape.node === source.uri);

let person = sourceShape;
return <div>{person.name}</div>;
});

Auto updates on changes in the graph

Linked components automatically rerender when the properties of their source are changed in the graph.