JSX
Why use it
React argues that rendering logic is intrinsically coupled to other UI logic, such as binding events in the UI, notifying the UI when state changes at certain moments, and displaying prepared data in the UI.
React does not use artificial separation of markup and logic into separate files. Instead, it separates concerns by storing both together in loosely coupled units called components.
React does not mandate the use of JSX, but most of the time it is visually helpful when putting JSX and UI together in JavaScript code. It also enables React to display more useful error and warning messages.
What to focus on
-
Because JSX is syntactically closer to JavaScript than HTML, the React DOM uses camelCase (small camel name) to define attribute names rather than the naming convention for HTML attribute names. For example, the class in JSX becomes className and tabIndex becomes TabIndex.
-
JSX protects against injection attacks: The React DOM escapes by default before rendering all input. It ensures that you never inject content into your application that you didn’t explicitly write. All content is converted to a string before rendering. This effectively prevents XSS (cross-site scripting) attacks.
-
JSX can be translated into a function call called react.createElement () using Babel(@babel/preset- React) without a processor such as webpack Loader
The following two ways are completely equivalent
const element = (
<h1 className="greeting">
Hello, world!
</h1>)
Copy the code
const element = React.createElement(
'h1'./* type */
{className: 'greeting'}, /* props */
'Hello, world! '/* children */
);
Copy the code
ReactElement
Common fields and XSS
This is an extension of createElement, which is essentially a React Object:
- Key: The key of the component, mainly used in the Virtual DOM, compare diff and Move Element
- Props: Component properties, derived from a parent component or HOC, or similar external passes
- Ref: the current DOM reference
- Type: indicates the component type
- _owner: is the React Component that creates the React Component. The null value is null
$$typeof
: in the early React (0.13) releaseIt is easy to$$typeof is used for field names and Symbol is used for value
React resolves this problem in two ways :(see why-do-react-elements have-typeof property)
- Encoding: New libraries like React will escape (client) - Data transfer: JSON does not support $$property names, so the property will be filtered out (server)Copy the code
Object vs ReactObject
How to tell whether an object is a React object? React provides the isValidElement method
/**
* Verifies the object is a ReactElement.
* See
https://reactjs.org/docs/react-api.html#isvalidelement
* @param {? object} object
* @return {boolean} True if `object` is a ReactElement.
* @final* /
export function isValidElement(object) {
return (
typeof object === 'object'&& object ! = =null &&
object.$$typeof === REACT_ELEMENT_TYPE
);
}
Copy the code
Fiber node
The declaration in the code is as follows
function FiberNode(
tag: WorkTag,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
) {
// Instance
// Static data store properties
// Define the type of optical fiber. It is used in the reconciliation algorithm to determine what needs to be done. As mentioned earlier, the work depends on the type of the React element. Function createFiberFromTypeAndProps will React element is mapped to the corresponding node type optical fiber
this.tag = tag;
this.key = key;
this.elementType = null;
// Define the function or class associated with this fiber. For class components, it points to constructors, and for DOM elements, it specifies HTML tags. I often use this field to learn what elements fiber nodes are associated with.
this.type = null;
// Save references to components, DOM nodes, or other React element types associated with fiber nodes. In general, we can say that this property is used to hold the local state associated with the fiber.
this.stateNode = null;
// Fiber
// Attributes related to the Fiber relationship, used to generate the Fiber Tree structure
this.return = null;
this.child = null;
this.sibling = null;
this.index = 0;
this.ref = null;
// Dynamic data & state-related properties
// New props, new props, nextProps
this.pendingProps = pendingProps;
// prev props, props for creating output Fiber during the last rendering
this.memoizedProps = null;
// Queues for status updates, callbacks, and DOM updates, as well as updates generated by Fiber components, are placed in this queue
this.updateQueue = null;
// Input the updated Fiber state last time
this.memoizedState = null;
// A list of contexts, Events that this Fiber depends on
this.dependencies = null;
/ / conCurrentMode and strictMode
// The coexistence mode indicates whether the subtree is rendered asynchronously by default
// When Fiber is first created, it inherits its parent Fiber
this.mode = mode;
// Effects
// The current Fiber phase requires tasks, including: placeholder, update, delete, etc
this.flags = NoFlags;
this.subtreeFlags = NoFlags;
this.deletions = null;
// Priority scheduling related attributes
this.lanes = NoLanes;
this.childLanes = NoLanes;
// Current tree and Working in Prgoress tree associate attributes
// In the FIber tree update process, each FIber has its corresponding FIber
// We call this current <==> workInProgress
// Will point to each other after rendering
this.alternate = null;
// The related time recorded by the profiler
if (enableProfilerTimer) {
// this.actualDuration Actual render duration (milliseconds)
// this.actualStartTime Render start time
// this.selfBaseDuration
// this.treeBaseduration subtree rendering duration
// Note: The following is done to avoid a v8 performance cliff.
}
// Debug related
if (__DEV__) {
// This isn't directly used but is handy for debugging internals:}}Copy the code
Type conversion (emphasis)
Each component in React has a UI representation that we can call the view or template returned from the Render method. Below is the sample code ClickCounter
<button key="1" onClick={this.onClick}>Update counter</button>
<span key="2">{this.state.count}</span>
Copy the code
JSX to ReactElement
After the template passes through the JSX compiler, you end up with a bunch of React elements. This is actually returned from the Render React component’s methods, not HTML. Since we don’t need to use JSX, we can rewrite the component’s Render method ClickCounter as follows
class ClickCounter {...render() {
return [
React.createElement(
'button',
{
key: '1'.onClick: this.onClick
},
'Update counter'
),
React.createElement(
'span',
{
key: '2'
},
this.state.count
)
]
}}
Copy the code
The call to Render in the react. createElement method creates two data structures, as shown below:
[{$$typeof: Symbol(react.element),
type: 'button'.key: "1".props: {
children: 'Update counter'.onClick: () = >{... }}}, {$$typeof: Symbol(react.element),
type: 'span'.key: "2".props: {
children: 0}}]Copy the code
You can see the $$Typeof property in the React Object, which uniquely identifies the React Element. The element attributes described by props are then passed to the React. CreateElement function.
The React element of ClickCounter does not have any props or keys:
{
$$typeof: Symbol(react.element),
key: null.props: {},
ref: null.type: ClickCounter
}
Copy the code
ReactElement to FiberNodes
During reconciliation, each React element’s data returned from the Render method is merged into the Fiber Tree. Each ReactElement has a corresponding Fiber Node that holds the variable data structure of the component state and DOM. Unlike the React element, Fiber is not recreated on every renderer.
In React, the framework performs different activities depending on the type of the React element. In our example application, ClickCounter calls the lifecycle and render methods for the class component, and DOM mutation is performed for the SPAN host component (DOM node). Therefore, each React element is converted to a Fiber node of the appropriate type, which describes the work that needs to be done.
You can think of Fiber as a data structure that represents some work to be done or, in other words, a unit of work. Fiber’s architecture also provides a convenient way to track, schedule, pause, and abort work.
First converts elements React to a Fiber, React to use the data elements create Fiber in createFiberFromTypeAndProps function. In subsequent updates, React reused Fiber and updated the necessary attributes only with data from the corresponding React element. React elements with the same key are no longer returned from the Render method, React may also need to move or remove nodes in the hierarchy based on prop.
React creates a Fiber node for each React element. You can use the ReactElement Tree to create a Fiber Tree. In our sample application, it looks like this:
All Fiber Nodes are connected via a linked list: Child, Sibling, and return.
Previous Article: React18 Technology Overview – Basics juejin.cn/post/700813…
The next notice: source code implementation