sunny
sunny

Reputation: 125

Creating div in function (React)

I have an exercise where I have to make an input and a button. When I click the button, there has to be created a div/span below, which prints the text which is in input. If I change the text in input, it has to be refreshed in that div/span only when I click the button again. I tried to do it with makeDiv function, but it doesn't do anything. I made console.log(event.target.value) and it handles the text which is in input, but nothing happens then.

My code:

import {useState} from "react"
function About() {
    
    const [initialValue,setInitialValue] = useState('')
    const handleValueChange = (event) => {
        console.log(event.target.value)
        setInitialValue(event.target.value)
    }
    const makeDiv = () => {
        return (<div>Value: {initialValue}</div>)
    }
    return(
    <div>
        

        <button onClick={makeDiv}>click me</button>
       <div><input type="text" onChange={handleValueChange} /></div>


    </div>
        )
}
export default About

edit:

What if I wanted to make an exercise very similar to that, but now, I have to add <li>text in input</li> to <ul> each time I click the button. So when I click the button, I add one li to the list, I tried like this, but it doesn't compile:

import {useState} from "react"
function About() {
   
   
   

    const [initialValueLastExercise, setInitialValueLastExercise] = useState([])
    const [ValueLE, setValueLE] = useState([])
    const handleValueChangeLE = (event) => {
        console.log(event.target.value)
        setInitialValueLastExercise([...initialValueLastExercise, event.target.value])
    }
    const showListWithText = () => {
        setShouldDisplayText(true)
        setValueLE(initialValueLastExercise)
    }


    return(
    <div>
   

       
        <button onClick={showListWithText}>click me to refresh the list</button>
        <div><input type="text" onChange={handleValueChangeLE} /></div>
        {shouldDisplayText && <div><ul>
            {
                
                for (let i =0; i<initialValueLastExercise.length; i++) {
                <li>{initialValueLastExercise[i]}</li>

                }




        }</div></ul>}


    </div>
        )
}
export default About

Upvotes: 0

Views: 2024

Answers (4)

M.Hassan Nasir
M.Hassan Nasir

Reputation: 861

This will refresh the value of the div on button click only as you have mentioned in the question.

import {useState} from "react"
function App() {
    
    const [initialValue,setInitialValue] = useState('')
    const [displayText, setDisplayText] = useState(false)
    const [Value,setValue] = useState('')
    const handleValueChange = (event) => {
        setInitialValue(event.target.value)
    }
    const showText = () => {setDisplayText(true)
    setValue(initialValue)};
return(
    <div>
       <button onClick={showText}>click me</button>
       <div><input type="text" onChange={handleValueChange} /></div>
       {displayText && <div>Value: {Value}</div>}
    </div>
        )
}
export default App

Solution for the Edited Question.

import {useState} from "react"
function App() {
    
    const [initialValue,setInitialValue] = useState('')
    const [displayText, setDisplayText] = useState(false)
    const [Value,setValue] = useState([])
    const handleValueChange = (event) => {
        setInitialValue(event.target.value)
    }
    const showText = () => {setDisplayText(true)
    setValue([...Value,initialValue])};
return(
    <div>
       <button onClick={showText}>click me</button>
       <div><input type="text" onChange={handleValueChange} /></div>
       <ul>{displayText && Value.length > 0  && 
         Value.map((i) => {
          return <li>Value: {i}</li>
       })}</ul>
    </div>
        )
      }
export default App

Upvotes: 1

VersifiXion
VersifiXion

Reputation: 2292

1st possibility - close to your code source

Don't forget to bind initialValue to the input and to add makeDiv content to the JSX :

return (
<div>
  <button onClick={makeDiv}>click me</button>
  <input type="text" onChange={handleValueChange} value={initialValue} />
  {makeDiv}
</div>
)

2nd possibility - with another approach

return (
<div>
  <button onClick={makeDiv}>click me</button>
  <input type="text" onChange={handleValueChange} value={initialValue} />
  {initialValue && <div>{initialValue}</div>}
</div>
)

Upvotes: 0

Quentin
Quentin

Reputation: 944054

Your approach is fundamentally wrong.

You should:

  • Store all the data about the component in the state
  • Render the output based on the state

So:

You need two state variables:

  • currentInputValue (because you need to store the value to display and edit in input)
  • selectedValue (because you need to store the value to be displayed in the div)

When onChange fires, update currentInputValue with the value of the input.

When onClick fires, update selectedValue with the current value of currentInputValue

When you return your data, include something like:

{selectedValue && <div>{selectedValue}</div>}

… to output a div containing the selected value only if there is a truthy value (the default empty string isn't truthy so the div won't be output then)

Upvotes: 0

Ron B.
Ron B.

Reputation: 1540

One way to do it is to create another state variable which indicates whether the div you're trying to make should be displayed and then render it conditionally. Something like

import {useState} from "react"
function About() {
    
    const [initialValue,setInitialValue] = useState('')
    const [shouldDisplayText, setShouldDisplayText] = useState(false)
    const handleValueChange = (event) => {
        console.log(event.target.value)
        setInitialValue(event.target.value)
    }
    const showDivWithText = () => setShouldDisplayText(true);
return(
    <div>
        

        <button onClick={showDivWithText}>click me</button>
       <div><input type="text" onChange={handleValueChange} /></div>
       {shouldDisplayText && <div>Value: {initialValue}</div>}


    </div>
        )
}
export default About

Upvotes: 0

Related Questions