Hossein Fallah
Hossein Fallah

Reputation: 2539

How to call parent function from children in composition?

I want to create an Input component to be used to compose new form elements.

const Input = ({ value, children }) => {

    const [currentValue, setCurrentValue] = useState();

    return <div className='input'>
        {children}
    </div>
};

And my Text component would be:

const Text = (props) => {
    return <Input {...props}>
        <input 
            type='text'
            value={/*how to bind to currentValue of Input*/}
            onChange={/*how to call Input's setCurrentValue here*/}
        />
    </Input>
}

I need to store currentValue state in parent, because I need to manage it for many different inputs.

Also I'm stuck at how to call parent's setCurrentValue on child's onChange method.

Any help is appreciated.

Update: CodeSandbox

Update 2: Real code from my repository

Upvotes: 1

Views: 628

Answers (2)

tanmoy
tanmoy

Reputation: 1438

Solutions:

  • Context API
  • Pass props to children
  • Use children as funciton & pass relevant

Send that reference somehow using any method you see fit.

My preference: Composition with function


const Input = ({ value, children }) => {

    const [currentValue, setCurrentValue] = useState();

    const handlChange = (e) => {
       setCurrentValue(e.target.value);
    };

    return <div className='input'>
        {children(handlChange)}
    </div>
};

const Text = (props) => {
    return <Input {...props}>
        { (handleChange) => (
           <input 
            type='text'
            onChange = ( handleChange }
           />
        ) }
    </Input>
}

Explanations:

Upvotes: 1

F.E
F.E

Reputation: 838

Please try like this.

// pass props to children.

const Input = ({ value, children }) => {

const [currentValue, setCurrentValue] = useState();

return <div className='input'>
        {React.cloneElement(child, {onChange: setCurrentValue, value: currentValue}))}
    </div>
};

// using props in childern.

const Text = (props) => {
return <Input {...props}>
        {
            ({onChange, value})=> (
                <input 
                   type='text'
                   value={value}
                   onChange={(e)=>onChange(e.target.value)}
                />
            )
        }
    </Input>
}

Upvotes: 1

Related Questions