0

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'/>
    )
}

2 Answers 2

1

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>

Sign up to request clarification or add additional context in comments.

2 Comments

One thing though, now the first input on each fragment is synchronized? If you type something into one it shows up in the other...
Sorry, You want to synchronise both the inputs, is that what you are looking for?
1

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>
            </>
        )
    }

Comments

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.