Reuse ReactJS component

63 views Asked by At

I have built a ReactJS component for rendering emoction. Separate component can be built for each emoction, but I want to use one component but pass separate emoction as required.

This is what works so far:

emoction.js

import { faHeart } from "@fortawesome/free-solid-svg-icons";
import { faHeartBroken } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useState } from 'react';

const Emoction = () => {    
    return (
        <FontAwesomeIcon icon={faHeart} />
    );
};

export default Emoction;

emoction_hb.js

import { faHeart } from "@fortawesome/free-solid-svg-icons";
import { faHeartBroken } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useState } from 'react';

const EmoctionHb = () => {    
    return (    
        // <input type="text" />
        <FontAwesomeIcon icon={faHeartBroken} />
    );
};

export default EmoctionHb;

Now, I am bundling these two components as:

expanded_content.js

import Emoction from "../emoctions/emoctions";
import EmoctionHb from "../emoctions/emoctions_hb";
import styled from "@emotion/styled";

import { faHeartBroken } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { Component } from 'react';

const Merged = styled.div`
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
`;

const expandedContent = () => {
    return(
      <div>
        <Merged>
            <Emoction/>
            <EmoctionHb/>
        </Merged>
      </div>
    )
    };
    
export default expandedContent;

which when I rendered using App.js

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';

import expandedContent from './components/merged_component/expanded_content'

class App extends React.Component {     
    render(){
        return(
            <Router>
            <>            
            <Route path='/ExpandedContent' exact component={expandedContent}/>
            </>
            </Router>
        )        
    }   
}
export default App;

gives me.

bundled emoctions


What I am trying to do is that instead of creating a component called emoctions_hb.js I want to reuse emoction.js by passing "faHeartBroken" as the value in it. If emoction.js is called without any value, I want it to use "faHeartBroken" as default value.

Tried following on to create Parent-Child relationship using https://webomnizz.com/change-parent-component-state-from-child-using-hooks-in-react/ but it did not work out for me.

2

There are 2 answers

3
Branislav Lazic On

Just pass the icon as a prop and set the default value to faHeartBroken:

const Emoction = ({ faIcon = faHeartBroken }) => {    
    return (
        <FontAwesomeIcon icon={faIcon} />
    );
};
0
Will Sanders On

It looks like you're importing useState but you're not implementing it anywhere. You could try implementing state in your expanded_content.js file and pass that down to your child component emoction.js, like this:

const ExpandedContent = () => {

    const [heart, setHeart] = useState(true)

    return(
      <div>
        <Emoction heart={heart} setHeart={setHeart}/>
      </div>
    )
    };
    
export default ExpandedContent;

Notice that you will need to change the name of your component. See the docs here https://reactjs.org/docs/hooks-rules.html. Then, inside of your Emoction component you will have access to heart which is set to true by default and you can also implement some logic to toggle the state using the function setHeart which is passed down from ExpandedContent:

const Emoction = ({heart, setHeart}) => {
    
    const handleHearts = () => {
        setHeart(heart => !heart)
    }
    return (
       heart ?  <FontAwesomeIcon icon={faHeart} /> : <FontAwesomeIcon icon={faHeartBroken} />
    );
};

export default Emoction;

By using a ternary statement to return your component you can decide to show faHeart or faHeartBroken depending on the current state. All you need to do is add the functionality wherever you need it.