I know, this topic has been handeled a lot, but I am still lost in my particular example. I have a react-select component, which is a part of another component, which is a part of App component.
SubjectSelect.tsx
export default function SubjectSelect({handleChange, value}) {
return (
<>
<Select
placeholder="Choose subject"
value={value} // set selected value
onChange={handleChange} // assign onChange function
/>
<div><b>Your choice: </b> {value} </div>
</>
)
}
FormStepOne.tsx
import SubjectSelect from "../components/SubjectSelect";
export const SubjectSelector = ({value, handleChange}) => {
return (
<>
<h1 className="text-3xl font-bold underline">
Hi there! Please select book subject
</h1>
<SubjectSelect value={value} onChange={handleChange}/>
</>
);
}
And App.tsx
import React, { useState } from 'react'
import { SubjectSelector } from '../formSteps/stepOne'
import { ShowcaseBooks } from '../formSteps/stepTwo'
const options = [
{ value: 'fiction', label: 'Fiction' },
{ value: 'science', label: 'Science' },
]
export default function App() {
const [books, setBooks] = useState('')
const [selectedValue, setSelectedValue] = useState('');
const handleChange = e => {
setSelectedValue(e.value);
alert('huhu')
}
const value = options.find(obj => obj.value === selectedValue)
return (
<div className="bg-blue-200">
<div className="container mx-auto py-36 bg-blue-200">
<div className="mt-12 px-96">
<SubjectSelector
options={options}
value={value}
onChange={handleChange}/>
<ShowcaseBooks books={books}/>
</div>
</div>
</div>
)
}
Somehow I am not passing the props right, so that my components showcase several errors. App.tsx complains about options and onChange, but I am lost and don't reallyfully undertand what is wrong and how to pass props corretly, so my App.js and therefore Showcase books "know" the selectdValue.
CodePudding user response:
The problem is you pass the handleChange
function to SubjectSelector
on the onChange
prop, while that component is expecting it on a prop named handleChange
.
In App.tsx you need something like this
<SubjectSelector
options={options}
value={value}
handleChange={handleChange}/> // This is the fix
Because when you do this
export const SubjectSelector = ({value, handleChange}) =>
You're telling the component the name of the props to expect. You need to change your Subject selector in a similar manner.
CodePudding user response:
For first loading, the prop value
you send is empty (because change event is not triggered). so It will turn your app into error.
So you need to check it not empty
before parse it to HTML
SubjectSelect.tsx
export default function SubjectSelect({ options, handleChange, selectedVal }) {
return (
<>
<select
value={selectedVal && selectedVal.value} // set selected value
onChange={handleChange} // assign onChange function
>
<option>Choose subject</option>
{options.map((item: any) => {
return (
<option key={item.value} value={item.value}>
{item.label}
</option>
);
})}
</select>
<div>
<b>Your choice: </b> {selectedVal && selectedVal.value}
</div>
</>
);
}
FormStepOne.tsx
import SubjectSelect from "./SubjectSelect";
const SubjectSelector = ({ selectedVal, handleChange, options }) => {
return (
<>
<h1 className="text-3xl font-bold underline">
Hi there! Please select book subject
</h1>
<SubjectSelect
options={options}
selectedVal={selectedVal}
handleChange={handleChange}
/>
</>
);
};
export default SubjectSelector;
And do not use value
as variable
name or prop
to avoid conflict with key
of object.
Getting value from change event should be e.target.value
import React, { useState } from "react";
import SubjectSelector from "./SubjectSelect";
const options = [
{ value: "fiction", label: "Fiction" },
{ value: "science", label: "Science" }
];
export default function App() {
const [selectedValue, setSelectedValue] = useState('');
const handleChange = (e: any) => {
setSelectedValue(e.target.value);
alert(e.target.value);
};
const selectVal = options.filter((obj) => obj.value === selectedValue)[0];
return (
<div className="bg-blue-200">
<div className="container mx-auto py-36 bg-blue-200">
<div className="mt-12 px-96">
<SubjectSelector
options={options}
selectedVal={selectVal}
handleChange={handleChange}
/>
</div>
</div>
</div>
);
}
You can check my complete answer here. I hope it might helps you
https://codesandbox.io/s/delicate-smoke-n0eyjc?file=/src/App.tsx:0-804