* Import Scheduler directly, not via host config We currently schedule asynchronous tasks via the host config. (The host config is a static/build-time dependency injection system that varies across different renderers — DOM, native, test, and so on.) Instead of calling platform APIs like `requestIdleCallback` directly, each renderer implements a method called `scheduleDeferredCallback`. We've since discovered that when scheduling tasks, it's crucial that React work is placed in the same queue as other, non-React work on the main thread. Otherwise, you easily end up in a starvation scenario where rendering is constantly interrupted by less important tasks. You need a centralized coordinator that is used both by React and by other frameworks and application code. This coordinator must also have a consistent API across all the different host environments, for convention's sake and so product code is portable — e.g. so the same component can work in both React Native and React Native Web. This turned into the Scheduler package. We will have different builds of Scheduler for each of our target platforms. With this approach, we treat Scheduler like a built-in platform primitive that exists wherever React is supported. Now that we have this consistent interface, the indirection of the host config no longer makes sense for the purpose of scheduling tasks. In fact, we explicitly do not want renderers to scheduled task via any system except the Scheduler package. So, this PR removes `scheduleDeferredCallback` and its associated methods from the host config in favor of directly importing Scheduler. * Missed an extraneous export
react-reconciler
This is an experimental package for creating custom React renderers.
Its API is not as stable as that of React, React Native, or React DOM, and does not follow the common versioning scheme.
Use it at your own risk.
API
const Reconciler = require('react-reconciler');
const HostConfig = {
// You'll need to implement some methods here.
// See below for more information and examples.
};
const MyRenderer = Reconciler(HostConfig);
const RendererPublicAPI = {
render(element, container, callback) {
// Call MyRenderer.updateContainer() to schedule changes on the roots.
// See ReactDOM, React Native, or React ART for practical examples.
}
};
module.exports = RendererPublicAPI;
Practical Examples
A "host config" is an object that you need to provide, and that describes how to make something happen in the "host" environment (e.g. DOM, canvas, console, or whatever your rendering target is). It looks like this:
const HostConfig = {
createInstance(type, props) {
// e.g. DOM renderer returns a DOM node
},
// ...
supportsMutation: true, // it works by mutating nodes
appendChild(parent, child) {
// e.g. DOM renderer would call .appendChild() here
},
// ...
};
For an introduction to writing a very simple custom renderer, check out this article series:
The full list of supported methods can be found here. For their signatures, we recommend looking at specific examples below.
The React repository includes several renderers. Each of them has its own host config.
The examples in the React repository are declared a bit differently than a third-party renderer would be. In particular, the HostConfig object mentioned above is never explicitly declared, and instead is a module in our code. However, its exports correspond directly to properties on a HostConfig object you'd need to declare in your code:
- React ART and its host config
- React DOM and its host config
- React Native and its host config
If these links break please file an issue and we’ll fix them. They intentionally link to the latest versions since the API is still evolving. If you have more questions please file an issue and we’ll try to help!