Home > other >  HOC with functional component
HOC with functional component

Time:05-07

I'm trying to make a simple HOC (Higher Order Function) with a functional component IN React.js. I have done the following, and it's compile, but nothing is shown on my localhost..?

//App.js
import React from 'react';
import HOC from './HOC';
import InnerCom from './InnerCom';
import './style.css';

export default function App() {

  const HOCBtn = HOC(InnerCom)

  return (
    <>
      <HOCBtn btnTxt="Click here!" />
    </>
  )
}


// HOC.js
import React from "react";

export default function HOC(WrappedComponent) {
    return function (props) {
        <div style={{ borderColor: "pink", borderStyle: "solid", borderWidth: "5px"}}>
            <WrappedComponent {...props}/>
        </div>
    }
}


// Innercom.js
import React from "react";

export default function InnerCom(props) {
    return (
        <button>{props.btnText}</button>
    )
}

CodePudding user response:

So right now how you have it I wouldn't say its a Higher Order Component since its just a wrapping a div around the component an HOC is when a component consumes a component and extends it's logic. So how I would approach this in functional components is (I did wrote this up in a sand box so you may have to do a little tweaking as far as adding export defaults back in):

import { useEffect, useState } from "react";

function InnerCom(props) {
  return <button>{props.btnTxt}</button>;
}

function HOC(props) {
  return (
    <div
      style={{
        borderColor: "pink",
        borderStyle: "solid",
        borderWidth: "5px"
      }}
    >
      {props.children}
    </div>
  );
}

export default function App() {
  return (
    <>
      <HOC>
        <InnerCom btnTxt="Click here!" />
      </HOC>
    </>
  );
}

Now as far as for my comment earlier about HOC say you want to access the btnText Prop from InnerCom in the HOC component and change the border color based on the text (this would be extending functionality) you would access the btnText prop like props.children.props.btnText heres an example of what the HOC component would look like:

function HOC(props) {
  const [bordeColor, setBorderColor] = useState("pink");

  useEffect(() => {
    if (props.children.props.btnTxt === "Click here!") {
      setBorderColor("blue");
    } else {
      setBorderColor("pink");
    }
  }, []);

  return (
    <div
      style={{
        borderColor: bordeColor,
        borderStyle: "solid",
        borderWidth: "5px"
      }}
    >
      {props.children}
    </div>
  );
}

CodePudding user response:

@William's answer is very informative and maybe helps you see that .children is implicitly set on props when a component is nested within another. Ie, you do not have to set btnText like that.

<Button>Hello</Button>
<A><B>Hello</B></A>
function Button(props) {
// props.children == "Hello"
// ...
}
function A(props) {
// props.children == <B>Hello</B>
// ...
}

function B(props) {
// props.children == "Hello"
// ...
}

This behavior is very useful and eliminates many of the naive cases where higher-order components are written but not actually required.

function styled(Tag, style = {}) {
  return props => <Tag style={style} {...props} />
}

const Box =
  styled("div", {
    borderColor: "pink",
    borderStyle: "solid",
    borderWidth: "5px"
  })
  
const Button =
  styled("button", {fontSize: "3rem", width: "100%"})

function App() {
  return (
    <Box>
      <Button onClick={e => console.log("hello")}>
        Click here
      </Button>
    </Box>
  )
}

ReactDOM.render(<App/>, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.development.js"></script>
<div id="app"></div>

  • Related