簡體   English   中英

為什么當一個組件被包裹在高階組件中時,新組件沒有任何原始組件的 static 方法?

[英]Why when a component is wrapped inside a High Order Component, the new component does not have any of the static methods of the original component?

我在React 文檔中讀到了它,但我不明白為什么會這樣。

此外,如果您能描述一個實際示例,我將不勝感激,在該示例中,可以將一個 static 方法附加到一個組件,該方法一旦包裝在 HOC 中就會丟失。 React 文檔討論了 Relay 容器,但我從未使用過它,我需要一個更簡單的示例。

這是一個更強大的示例。 static 值在使用高階組件時不可用的原因(例如,下面示例中的enhance )是因為組件正在組合或包裝它被另一個組件包裝。 因此,生成的組件沒有傳入組件的 static 方法(除非像下面示例中的enhanceAndHoist那樣顯式復制)。

但是,通常希望所有 static 方法都發生這種情況,這些方法可以使用文檔中所述的hoist-non-react-statics package 來完成,並且實際上被許多其他提供更高階組件的包使用。

For example, the last line in react-redux 's connect method is to hoist statics: https://github.com/reduxjs/react-redux/blob/b6b47995acfb8c1ff5d04a31c14aa75f112a47ab/src/components/connectAdvanced.js#L432

// Line from react-redux
return hoistStatics(Connect, WrappedComponent)

 const enhance = Wrapped => { return class Enhanced extends React.Component { render() { return <Wrapped injectedProp="foo" />; } }; }; const WrappedComponent = props => <div>{props.injectedProp}</div>; // Define a static method WrappedComponent.staticValue = "baz"; // Now apply a HOC const EnhancedComponent = enhance(WrappedComponent); console.log(`WrappedComponent.staticValue: ${WrappedComponent.staticValue}`); // "baz" console.log(`EnhancedComponent.staticValue: ${EnhancedComponent.staticValue}`); // undefined const enhanceAndHoist = Wrapped => { const result = class Enhanced extends React.Component { render() { return <Wrapped injectedProp="foo" />; } }; // Manually "hoist" the static value. result.staticValue = Wrapped.staticValue; return result; }; // Now apply a HOC const EnhancedAndHoistedComponent = enhanceAndHoist(WrappedComponent); console.log(`WrappedComponent.staticValue: ${WrappedComponent.staticValue}`); // "baz" console.log( `EnhancedAndHoistedComponent.staticValue: ${ EnhancedAndHoistedComponent.staticValue }` ); // "baz" function App() { return <EnhancedComponent />; } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);
 <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div>

請注意我。 我也在學習。 但我相信,我的回答是有意義的。 雖然不明確。

Static 實體的 Class 沒有被考慮的原因,一般來說,是因為 React 沒有考慮類是什么,但 Class 由什么組成(類的最終產品)。

React.createElement()方法通過調用 Class 獲取屬性值和組件的實例。考慮一個示例組件:

<Text className="danger">Hello React</Text>

Babel 轉譯后的大致組件:

  React.createElement(
    Text, // Component
    { className: 'danger' }, // Component className
    'Hello React' // Component children
  )

該方法的第一個參數必須是一個HTMLElement ,其他道具和孩子將被傳遞到其中。 這意味着 Class 被實例化,並返回 Object。

我正在考慮@skovy 的示例。 在定義 static 方法並將其傳遞給高階組件后,它返回 Object 以及構建 HTML 所需的屬性:

const WrappedComponent = props => <div>{props.injectedProp}</div>;

// Define a static method
WrappedComponent.staticValue = "baz";

console.log((Object.getOwnPropertyNames(<WrappedComponent />)))
// Logs : ['$$typeof', 'type', 'key', 'ref', 'props', '_owner', '_store', '_self', '_source']

console.log(Object.getOwnPropertyDescriptors(React.createElement(WrappedComponent)))
// Logs : {$$typeof: {…}, type: {…}, key: {…}, ref: {…}, props: {…}, …}

它們不是來自 Class,而是來自 Class,返回經過進一步處理的實例化 Object。

因為,從高階組件返回的組件本身是 Object,而不是 class。

const EnhancedComponent = enhance(WrappedComponent);

EnhancedComponent本身沒有任何關聯的 class 將 Static 實體僅添加到WrappedComponent的對象。 因為那是從<WrappedComponent />返回的內容 + 顯然對象不會從其類繼承 static 實體。

進一步的分析需要查看指向React.createElement() Reference 的Index.d.ts文件。 但 React 似乎沒有考慮 Class 中定義的內容。但只考慮它返回的內容。 並驗證相同。

有一個討論 - 但這個會有助於理解 - Static 屬性/方法在 React 中總體使用較少。

此外,新的 React 文檔指出了函數和函數式編程的方向,而不是使用類。

但是,如果需要使用。 最好單獨提取它們,然后再次明確地將它們寫入從 HOC 創建的新組件。

暫無
暫無

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

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