[英]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
屬性? 因為通常, type
是string
,而不是 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.