I'm new to nextjs/react so bare with me here. In my project I have multiple select elements with multiple options in each one. When an option is selected or changed I want to pass that value to another component. I was able to pass an onClick event to another component but when I tried a similar solution I wasn't able to get it to work. So the select elements are being mapped in Component A2, but the options for those elements are also being mapped in Component A3 and I need to pass the value to Component B2. You will see in my code I tried to pass it with the "handleOnChange". I'm not very good at explaining things so here is my code snippets, I hope this makes sense:
Parent Component
export default function Post({ globalProps, page, globalPages, sidebarProps }) {
const [addFlexItem, setAddFlexItem] = useState(false)
const [addFlexItemStyles, setFlexItemStyles] = useState()
return (
<Layout globalProps={globalProps}>
<main className={styles.container}>
<FlexSidebar sidebarProps={sidebarProps} onClick={() => setAddFlexItem(true)} handleOnChange={() => setFlexItemStyles()} />
<FlexContainer addFlexItem={addFlexItem} addFlexItemStyles={addFlexItemStyles} />
</main>
</Layout>
)
}
Component A1
const FlexSidebar = ({ sidebarProps, onClick, handleOnChange }) => {
return (
<aside className={styles.left_sidebar}>
<section className={styles.wrap}>
{/* we are padding the onClick to the child component */}
{container === true && <FlexSidebarContainer sidebarProps={sidebarProps} onClick={onClick} handleOnChange={handleOnChange} />}
{items === true && <FlexSidebarItems sidebarProps={sidebarProps} />}
</section>
</aside>
)
}
Component A2
const FlexSidebarContainer = ({ sidebarProps, onClick, handleOnChange }) => {
const options = sidebarProps.options
return (
<>
<p className={styles.warning}>{sidebarProps.containerWarningText}</p>
<button type="button" className="btn" onClick={() => onClick()}>
{sidebarProps.addItemBtn}
</button>
<form className={styles.form}>
{options.map((option, index) => {
return (
<div key={index} className={styles.form_item}>
<div className={styles.form_label_wrap}>
<label>{option.title}</label>
</div>
<FlexSidebarSelect options={option.items} handleOnChange={handleOnChange} />
</div>
);
})}
</form>
</>
)
}
Component A3
const FlexSidebarSelect = ({ options, handleOnChange }) => {
return (
<div className={styles.form_item_wrap}>
<select onChange={(value) => handleOnChange(value)}>
{options.map((item, index) => {
return (
<option key={index} value={item.value}>{item.item}</option>
)
})}
</select>
</div>
)
}
Component B1
const FlexContainer = ({ addFlexItem, addFlexItemStyles }) => {
return (
<section className={styles.right_content}>
<FlexItem addFlexItem={addFlexItem} addFlexItemStyles={addFlexItemStyles} />
</section>
)
}
Component B2
const FlexItem = ({ addFlexItem, addFlexItemStyles }) => {
const [isaddFlexItem, setaddFlexItem] = useState(addFlexItem)
useEffect(() => {
setaddFlexItem(addFlexItem)
}, [addFlexItem])
return (
isaddFlexItem ?
<div className={styles.flex_item}>
<div className={styles.flex_item_wrap}>
<div className={styles.flex_item_inner}>
</div>
<button className={styles.trash}>
</button>
</div>
</div>
: "empty"
)
}
I will add that if I change the code in Component A3 to this, im able to log the value, but I cant get it to work in the parent component.
const FlexSidebarSelect = ({ options, handleOnChange }) => {
const [value, setValue] = useState("")
const handleOptionChange = (e) => {
let value = e.target.value
setValue({
value
})
}
return (
<div className={styles.form_item_wrap}>
<select onChange={handleOptionChange}>
{options.map((item, index) => {
return (
<option key={index} value={item.value}>{item.item}</option>
)
})}
</select>
</div>
)
}