S.W.
S.W.

Reputation: 115

How can I reference a function inside a component from the outside?

I have an array of fragments that I'm passing into ChildComponent. The fragments must have onChange attributes set to a handler that exists inside the ChildComponent, but as they are written outside of it doing so breaks the app. I can't define the fragments inside ChildComponent and I can't define ChildComponent inside ParentComponent. How do I do this properly?

const fragments = [
    const Screen1 = () => {
        return (
            <>
                <input type="text" id="screen1_input1" onChange={onChangeHandler} />
            </>
        )
    };
    const Screen2 = () => {
        return (
            <>
                <input type="text" id="screen2_input1" onChange={onChangeHandler} />
            </>
        )
    };
]

ChildComponent.js

const ChildComponent = (props) => {
        let index = props.index
        const fragments = props.fragments
        
        const onChange = (e) => {
            //whatever
        }
        
        
        return (
            <>
                <h2 className="screens">
                    {fragments[index]()}
                </h2>
            </>
        )
    }

ParentComponent.js

import ChildComponent from './ChildComponent'

const ParentComponent = (props) => {
    let index = 3
    
    return (
        <ChildComponent index='3'/>
    )
}

Upvotes: 0

Views: 39

Answers (2)

Nithish
Nithish

Reputation: 5999

You can convert fragments array into a function which takes onChangHandler and return an array itself.

Below is the refactored code, for simplicity I'm just logging the input element id and the value that's being inputted.

const { Fragment } = React;

const fragments = (onChangeHandler) =>
  [
    <input type="text" id="screen1_input1" onChange={onChangeHandler} />,
    <input type="text" id="screen2_input1" onChange={onChangeHandler} />
  ];

const ChildComponent = ({ index, fragments }) => {
  const onChange = e => {
    const { target: {id, value} } = e;
    console.log(id, value);
  };

  return (
    <Fragment>
      <h2 className="screens">{fragments(onChange)[index]}</h2>
    </Fragment>
  );
};

const ParentComponent = props => {
  return <ChildComponent index={1} fragments={fragments}/>;
};

ReactDOM.render(<ParentComponent />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

<div id="react"></div>

Upvotes: 1

Sohaib
Sohaib

Reputation: 11297

Define fragments like this

const fragments = [
    const Screen1 = (onChangeHandler) => {
        return (
            <>
                <input type="text" id="screen1_input1" onChange={onChangeHandler} />
            </>
        )
    };
    const Screen2 = (onChangeHandler) => {
        return (
            <>
                <input type="text" id="screen2_input1" onChange={onChangeHandler} />
            </>
        )
    };
]

ChildComponent.js

const ChildComponent = (props) => {
        let index = props.index
        const fragments = props.fragments
        
        const onChange = (e) => {
            //whatever
        }
        
        
        return (
            <>
                <h2 className="screens">
                    {fragments[index](onChange)}
                </h2>
            </>
        )
    }

Upvotes: 1

Related Questions