Home > Mobile >  How to update prop value from child - React
How to update prop value from child - React

Time:07-23

I'm new and trying to do something but can't THINK of a way (that works) to do so. I have the following situation:

  • Array with 5 cells that can hold one char, I am sending each cell as a prop to an Input tag, in my custom Input react component I want to update that cell to hold a key, but can't do so.

My code:

import React, { useState, useEffect } from 'react'
import Input from './Input'
const makeWords = require('make-words')

function Body() {

    const [word, setWord] = useState(makeWords.getWordByLength(5)) //create new word 
    const [guess, setGuess] = useState('') //saves guess from user
    let information = ['','','','',''] //array with 5 cells

    useEffect(() => { //when information array gets updated, set the guess to the new array value (toString)
        setGuess(information.join(''))
    }, [information])

    return (
        <div>
            <h1 className='secret-word'>{word}</h1>
            <Input className='letter-guess' info={information[0]}/>
            <Input className='letter-guess' info={information[1]}/>
            <Input className='letter-guess' info={information[2]}/>
            <Input className='letter-guess' info={information[3]}/>
            <Input className='letter-guess' info={information[4]}/>
        </div>
    )
}

export default Body

and

import React, { useEffect, useState } from 'react'

function Input({ className, info }) {
    let [character, setCharacter] = useState('')//hold the character

    function onChangeEvent(event) { // handles key input to save character
        event.target.value = event.target.value.slice(-1)
        setCharacter(event.target.value)
    }

    return (
            <input type="text" className={className} onChange={onChangeEvent}/>// input tag
    )
}

export default Input

I would really appreciate any help especially one with explanation, thanks a lot!

CodePudding user response:

You are storing the state of the word in both the Input and Body components. It is generally not good practice to store the same state in two separate places. Try something like this instead:

function Body() {
    const [word, setWord] = useState(makeWords.getWordByLength(5))
    const [guess, setGuess] = useState('')
    const [information, setInformation] = useState(['','','','',''])

    useEffect(() => {
        setGuess(information.join(''))
    }, [information])

    return (
        <div>
            <h1 className='secret-word'>{word}</h1>
            <Input className='letter-guess' handleChange={setInformation} info={information} index={1} />
            <Input className='letter-guess' handleChange={setInformation} info={information} index={2} />
            <Input className='letter-guess' handleChange={setInformation} info={information} index={3} />
            <Input className='letter-guess' handleChange={setInformation} info={information} index={4} />
            <Input className='letter-guess' handleChange={setInformation} info={information} index={5} />
        </div>
    )
}

Then the Input component would look like this:

function Input({ className, handleChange, info, index }) {

    function updateInformation(e) {
        handleChange(() => {
            const newInfo = info;
            newInfo[index] = e.target.value;
            return newInfo;
            });
        }

        return (
            <input type="text" className={className} onChange={
            (e) => updateInformation(e)}/>
        )
    }

This code is probably too long but I think it gets the idea across. Pass the current state of information and the setInformation function as props to the Input. Then when any input changes, use the index to update the value and pass it to the setInformation function.

CodePudding user response:

I'm not quite sure I understood your problem, but I think you want to be able to modify the prop info that you receive from your parent.

In that case the simplest way to do that is to have a state with the value and the setter in the parent, and pass to the child both the value and the setter. The children now gets the value as a prop and also the function to modify that value when it wants.

  • Related