It is a key goal for React that the amount of the user code that executes before yielding back into React is minimal. This ensures that React retains the capability to schedule and split work in chunks according to what it knows about the UI. The control over scheduling would be harder for us to gain if we let the user directly compose views with a “push” based paradigm common in some variations of Functional Reactive Programming.
If you see something wrong on the screen, you can open React DevTools, find the component responsible for rendering, and then see if the props and state are correct. If they are, you know that the problem is in the component’s render() function, or some function that is called by render(). When something goes wrong, it is important that you have breadcrumbs to trace the mistake to its source in the codebase. The usage patterns that we see internally at Facebook help us understand what the common mistakes are, and how to prevent them early.
Any component that has the potential to adversely impact cyber supply-chain risk is a candidate for Component Analysis. So it is important that it doesn’t introduce new internal abstractions unless absolutely necessary. Verbose code that is easy to move around, change and remove is preferred to elegant code that is prematurely abstracted and hard to change. Having a single programming model lets us form engineering teams around products instead of platforms. Being renderer-agnostic is an important design constraint of React.
When we add new features, we try to anticipate the common mistakes and warn about them. We also try to go an extra mile to provide helpful developer warnings. For example, React warns you in development if you nest tags in a way that the browser doesn’t understand, or if you make a common typo in the API. Developer warnings and the related checks are the main reason why the development version of React is slower than the production version. For example, we maintain React DevTools which let you inspect the React component tree in Chrome and Firefox. We have heard that it brings a big productivity boost both to the Facebook engineers and to the community. There is an internal joke in the team that React should have been called “Schedule” because React does not want to be fully “reactive”.
On the other hand, any improvements to the core translate across platforms. We do, however, provide some global configuration on the build level. For example, we provide separate development and production builds. We may also add a profiling build in the future, and we are open to considering other build flags. If the props are wrong, you can traverse the tree up in the inspector, looking for the component that first “poisoned the well” by passing bad props Duty Calls down.
If there is a lot of repetitive manual work involved, we release a codemod script that automates most of the change. Codemods enable us to move forward without stagnation in a massive codebase, and we encourage you to use them as well. For example, we added a warning about unknown DOM props in React 15.2.0. However fixing this warning is important so that we can introduce the support for custom attributes to React. There is a reason like this behind every deprecation that we add. If we are confident that the change is not too disruptive and the migration strategy is viable for all use cases, we release the deprecation warning to the open source community. We are closely in touch with many users of React outside of Facebook, and we monitor popular open source projects and guide them in fixing those deprecations.
If something is offscreen, we can delay any logic related to it. If data is arriving faster than the frame rate, we can coalesce and batch updates. We can prioritize work coming from user interactions over less important background work to avoid dropping frames. Since you don’t call that component function but let React call it, it means React has the power to delay calling it if necessary. In its current implementation React walks the tree recursively and calls render functions of the whole updated tree during a single tick. However in the future it might start delaying some updates to avoid dropping frames. When we add a deprecation warning, we keep it for the rest of the current major version, and change the behavior in the next major version.