【问题标题】:React/Typescript: How do I pass and "type" props down through multiple componentsReact/Typescript:我如何通过多个组件向下传递和“键入”道具
【发布时间】:2021-12-04 15:45:36
【问题描述】:

在我的 React/Typescript 项目中,我遇到了一个挑战:

  1. 从 Child 组件我向下传递一个 prop class

    Child class={{ myBanner: styles.myBanner } />

    我输入class prop如下:

     import { SerializedStyles } from '@emotion/react';
    
     import { Class as MyCustomBannerClass } from './MyBanner/MyBanner.types';
    
     type Class = Partial<Record<'root', SerializedStyles>> & {
       myBanner: MyCustomBannerClass;
     };
    
     export type Props = {
       class: Class;
     };
    

  2. 在 Child 组件内我有 &lt;MyBanner/&gt; 组件,其中我还有一个 class 道具:

    export type Class = Partial<Record<'root', SerializedStyles>>;
    
    export type Props = {
      class?: Class;
    };
    
    <MyBanner class={props.class?.myBanner} />
    

一切正常。
现在,从 Parent 组件中,通过 Child&lt;MyBanner/&gt;
我可以从 @987654329 覆盖 Parent 中的 CSS 样式@组件。


挑战:

现在我有一个案例:

  • 孩子里面,我还有一个孩子&lt;AnotherChild/&gt;

  • &lt;AnotherChild /&gt; 内,我有&lt;MyBanner/&gt; 组件。

问题:

我如何通过两者传递和输入class={{ myBanner: styles.myBanner }...

  1. 孩子:&lt;Child class={{ myBanner: styles.myBanner } /&gt;

  2. 还有另一个孩子: &lt;AnotherChild class={???} /&gt;

...并将其传递给&lt;MyBanner class={props.class?.myBanner} /&gt;?

【问题讨论】:

    标签: reactjs typescript components react-props


    【解决方案1】:

    这看起来是一个可以通过使用React.useContext
    轻松解决的问题......换句话说,ContextAPI。这是关于它的official docs

    要专门解决您的问题,您可以像这样useContext
    Parent.tsx

    /** PARENT **/
    
    import React from 'react';
    import { SerializedStyles } from '@emotion/react';
    import { Class as MyCustomBannerClass } from './MyBanner/MyBanner.types';
    
    // define parent context
    type Class = Partial<Record<'root', SerializedStyles>> & {
      myBanner: MyCustomBannerClass;
    };
    
    interface Props {
      parentClass?: Class,
    };
    
    export const ParentContext = React.createContext({} as Props);
    
    export const Parent = props => {
      const parentClass = React.useRef({ myBanner: styles.myBanner });
    
      const contextProps = {
        parentClass: ..., // add props to be passed down
      };
    
      return (
        // We pass (or literally provide) "parentClass" (and more) 
        // to all the children of "Parent"
        <ParentContext.Provider value={{ ...contextProps }}>
          <Child />
        </ParentContext.Provider>
      )
    };
    

    Child.tsx

    // FIRST-CHILD
    
    import React from 'react';
    
    // define context
    type Class = Partial<Record<'root', SerializedStyles>>;
    
    interface Props {
      childClass?: Class,
    };
    
    export const ChildContext = React.createContext({} as Props);
    
    // define component
    export const Child = props => {
      const childClass = React.useRef({ ... })
    
      const contextProps = {
        childClass: ..., // add props to be passed down
      };
    
      return (
        // Both "MyBanner" and "AnotherChild" are provided with both `class` props
        // from "Parent" and "Child" and it can go on and on...
        <ChildOneContext.Provider value={{ ...contextProps }}> 
          <MyBanner />
          <AnotherChild />
        </ChildOneContext.Provider>
      )
    };
    

    AnotherChild.tsx(你可以在“MyBanner”中做同样的事情)

    // SECOND-CHILD
    
    import React from 'react';
    import { ParentContext } from './Parent';
    import { ChildContext } from './Child';
    
    // define component
    const AnotherChild = props => { 
      const { parentClass } = React.useContext(ParentContext);
      const { childClass } = React.useContext(ChildContext);
    
      return (
        <div className={ParentClass}>
          <div className={childClass}></div>
        </div>
      )
    };
    

    注意: 如果您希望子组件在任何情况下都覆盖 class 属性,您可以使用 useState 而不是 useRef 定义类,就像我在这种情况下所做的那样。


    也就是说,请记住,ContextAPI 旨在共享可被视为 React 组件树“全局”的数据,例如您的案例!

    【讨论】:

      猜你喜欢
      • 2019-03-13
      • 1970-01-01
      • 1970-01-01
      • 2020-08-20
      • 2021-11-23
      • 2021-01-26
      • 1970-01-01
      • 2018-08-22
      • 2018-11-22
      相关资源
      最近更新 更多