Reputation: 149
I created a component (it's actually a function but I think they're called components?) for a Select Field.
const useStyles = makeStyles((theme) => ({
formControl: {
minWidth: 120,
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}))
export default function SelectField() {
const classes = useStyles()
const [value, setValue] = React.useState("")
return(
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="age">Age</InputLabel>
<Select
labelId="age"
id="age"
label="Age"
key="index"
value={value}
onChange={(val) => setValue(val)}
>
<MenuItem value=""><em>None</em></MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
)
}
And I'm using this Select field on another "component" (I'll only show the import for that field).
import SelectField from './fields/select'
export default function CreateGame(){
const [questions, setQuestions] = React.useState([{
question: 'asdasdasd',
answer: '',
score: '',
age: ''
}])
const HandleField = (event, index, field) => {
let temp_questions = questions
temp_questions[index][field] = event.target.value
setQuestions(temp_questions)
console.log(questions)
}
const setAge = (e, index) => {
let questions_temp = questions
questions_temp[index]['age'] = e.target.value
setQuestions(questions_temp)
console.log(questions)
}
return(
<Card>
<CardContent>
<Typography>
Add Questions
</Typography>
{questions.map((value, index) =>
<Grid container spacing={1}>
<Grid item lg={2}>
<TextField
value={value['question']}
key={index}
label='Question'
variant='outlined'
onChange={e => HandleField(e, index, 'question')} />
</Grid>
<Grid item lg={2}>
<TextField
value={value['answer']}
key={index}
label='Answer'
variant='outlined'
onChange={e => HandleField(e, index, 'answer')} />
</Grid>
<Grid item lg={2}>
<TextField
value={value['score']}
label='Score'
key={index}
variant='outlined'
onChange={HandleField} />
</Grid>
<Grid item lg={5}>
<SelectField age={value['age']} setAge={setAge} index={index} />
</Grid>
</Grid>
)}
</CardContent>
<Button>Add</Button>
</Card>
)
}
I want to get my <SelectField />
's selected value and save it in my questions
state, specifically in the age
field. But I don't know exactly how to capture that value. I tried putting a value prop, but I don't think that's the correct way.
Upvotes: 0
Views: 54
Reputation: 370729
Keep the state only in the parent, and pass it down as a prop, as well as another prop - a function which, when called, sets the age in the parent.
You also need to correct the shape of onChange
- it accepts an argument of the event, not of the new value.
// in CreateGame
const setAge = i => (newAge) => {
setQuestions([
questions.slice(0, i),
{ ...questions[i], age: newAge },
questions.slice(i + 1),
]);
};
// ...
<Grid item lg={5}>
<SelectField age={questions.age} setAge={setAge(index)} />
</Grid>
export default function SelectField({ age, setAge }) {
// ...
<Select
value={age}
onChange={e => setAge(e.currentTarget.value)}
Upvotes: 1
Reputation: 968
You can go through these steps
- Step 1 Make an onchange event listener
<SelectField onChange={handleQuestion}/>
- Step 2 Use Hooks to make a state inside functional component
const [Question, setQuestion] = useState("")
- Step 3 Make the method that you had called in step 1
const handleQuestion = () =>{
//First get the value coming fron the onchange listener
console.log(e.target.value);
//Set the state to the question
setQuestion(e.target.value)
}
- Step 4 Pass the value to the question
<TextField
value={Question}//Pass the questions state value here
/>
Upvotes: 0