plasmy
plasmy

Reputation: 149

How can I get the value of a component I created?

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

Answers (2)

CertainPerformance
CertainPerformance

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

Fahad Shinwari
Fahad Shinwari

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

Related Questions