簡體   English   中英

為什么 React 組件是通過 `React.createElement()` 方法執行的?

[英]Why are React components executed through the `React.createElement()` method?

鑒於 React 組件本質上是 function:

const Component = ([props]) => React.createElement(type[, props [, ...children]]);

當我嘗試將其稱為任何正常的 function 時:

Component([props]); 

它不起作用。

同時,在 React 文檔中它是這樣調用的:

React.createElement(Component[, props]);

如何將組件用作type屬性? 因為通常, typestring ,而不是 function。

當我嘗試將其稱為任何正常的 function:...它按預期工作。

它可能不會拋出錯誤(盡管如果你使用鈎子會拋出錯誤),但在一般情況下它不會正常工作。 (如果您的 function 是無狀態的並返回調用createElement的結果,它可能會起作用。)

當您將組件傳遞給createElement時,React 不會調用您的組件 function ,它只是創建並返回一個 React 元素 object ,該元素存儲 function 和元素:

 const Example = ({value}) => { // (Returning a simple string to keep the example simple) console.log("Example called"); return `Hi there, value = ${value}`; }; console.log("Creating element (Example is never called)"); const element = React.createElement(Example, {value: "x"}); console.log("Element object:"); console.dir(element);
 .as-console-wrapper { max-height: 100%;important; }
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

如果您使用該元素,React稍后會調用 function(如果您不使用它,則永遠不會)。 通常它不止一次,因為大多數元素都被渲染了不止一次,並且 function 為每個渲染計算(除非你記住它並且memo function 說結果將與上次相同)。 因此,function 可以被稱為從不(如果元素從未使用過),或者重復(如果元素被使用並重新渲染)。

另外,React 在調用您的 function 之前在其末尾設置了一些內部事物,因此如果您的 function 使用鈎子,它知道在哪里存儲鈎子信息。 如果您調用直接使用鈎子的 function,則鈎子會拋出錯誤,因為未設置該上下文。

這是一個簡單的示例(直接使用createElement而不是通過 JSX,因為您的問題特別提到了createElement ):

 const { useState, createElement } = React; const Example = ({value}) => { const [counter, setCounter] = useState(0); console.log(`Example called with value = ${value}`); return createElement( "div", {value}, [ `Counter = ${counter}`, createElement( "input", { key: "input", type: "button", value: "+", onClick: () => setCounter(c => c + 1), } ) ] ); }; console.log("Creating element without using it (function is never called):"); const result = createElement(Example, {value: "not used"}); console.log("Creating element and using it (function is called for each re-render):"); const App = () => { return createElement(Example, {value: "used"}); }; ReactDOM.render( createElement(App), document.getElementById("root") );
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM