0

I have created a component, and I want to make it easy to use. I don't wanna call my component like the following way,

<myComponent {...someProps} />

I'm looking for a specific way, I'm still new in React I don't know exactly the name and how can I do it. is there any way to call my component as a hook or something similar, let's take this component as an example?

export const useComponent = (props) => {  
  const [show, setShow] = useState('show');
  
  const onShow = (value) => { setShow(value); }

  return (
    // Content
    <div className={show}>
      Component 
      <button onClick={onShow(hide)}>Hide</button>
    </div>
  );
}

I need to show what inside content using a function, like that

const onShow = useComponent();

//if I want to show it I will call onShow function
<button onClick={onShow('show')}>Show Component</button>

What I want basically is when I clicked on the 'Show Component' button I want to show the useComponent, without calling it inside HTML like . it's like it gonna be easy for to everyone use my component.

8
  • Sounds like what you're looking for is how to conditionally render a component. Commented Sep 13, 2021 at 14:26
  • No. For multiple reasons. 1 - You should never call a component function yourself. This leaves React out of the process entirely, and it can no longer manage state or lifecycle (your hooks will throw errors). 2 - onClick doesn't return anything. Conceptually it makes no sense for it to return anything. If it did, where would it render the JSX? Inside the button? Above it? Below? Commented Sep 13, 2021 at 14:26
  • @BrianThompson maybe there is a clean way to do that Commented Sep 13, 2021 at 14:30
  • move your show and setShow to the component that has the button. on click of the button set the show and conditionally render the Component based on the state show Commented Sep 13, 2021 at 14:36
  • I'm looking for a way to show it using a function inside Component. @Prasanna Commented Sep 13, 2021 at 14:39

2 Answers 2

1

One solution is to use a wrapper component using the Context API. This is, in my opinion, one of the advanced features of React. Super useful of course, but if you are a beginner, try creating just a component :) Anyway, you missed in your description, what the custom hook should do. If you need a more precise answer, try giving some more info :)

import React, { useState, createContext, useContext} from 'react';

export const ComponentContext = createContext(null);

/**
 * Don't forget to describe your provider
 * @param {object} args react args
 * @param {JSX.Element | Array<JSX.Element>} args.children children to show
 */
export const ComponentProvider = ({ children }) => {


  const [show, setShow] = useState('show');
  
  const onShow = (value) => { setShow(value); }

  return (
    <ComponentContext.Provider
      value={{ show, onShow }}
      children={children}
    />
  );
};

/**
 * Hook used to get the props you defined
 * @returns {{show:boolean,onShow:function}}
 */
export const useComponent = () => {
  const res = useContext(UserContext);
  return res;
};

You can then use your component in the wrapper or App.jsx

import React from 'react';
import { ComponentProvider } from './custom-hooks/ComponentProvider';
function App() {
  return (
    <ComponentProvider>
      <YourComponent />
    </ComponentProvider >
  );
} 

and finally, use the functions you need in the element

import { useComponent } from './custom-hooks/ComponentProvider';

...

const { onShow } = useComponent();

return (
   <button onClick={()=>onShow('show')}>Show Component</button>
);
Sign up to request clarification or add additional context in comments.

4 Comments

Not even close. You missed the part of the wrapper or App.jsx. :D You have to define the Context of the component in order to use "useComponent"
is there any way to avoid defining anything inside the HTML part,
On click has to be defined in the html. For more complex stuff, you could use useRef, but again, this is advanced react. Make sure to understand the simple things first :)
1

Edited:

I think you're looking for HOC. You can create Higher Order Component using useComponent and serve/provide wherever you need it by following example.

const withComponent = (WrappedComponent) => {
  const WithComponent = (props) => {
    function useComponent(status, setStatus) {
      return (
        <div>
          {status == "show" && <div>
            <p>Inner Contents</p>
            <button onClick={() => setStatus("hide")}>Hide Inner Contents</button>
          </div>}
          
        </div>
      );
    }
    return <WrappedComponent {...props} useCompoent={useComponent} />;
  };

  return WithComponent;
};

const App = (props) => {
  const { useCompoent } = props;

  const [status, setStatus] = useState("hide");

  const getUseComponent = useCompoent(status, setStatus);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      {getUseComponent}
      <button onClick={() => setStatus("show")}>
        Show Component
      </button>
    </div>
  );
};

export default withComponent(App);

You can move withComponent into separate file as well.

6 Comments

it's not clear how can I use HOC in my case
You can add button instead of P tag inside the useComponent function and trigger to hide/show function to display html (for ex. modal).
You can't return html & events when you call as a function. it will not render any html. So you need HOC to call as a function(in your desired way - without rendering the component as <myComponent/>).
I made a sandbox to show/hide inner function based on click codesandbox.io/s/react-managing-function-modal-externally-zpqyv Hope it will be useful
in your solution I need to call getUseComponent inside HTML.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.