skip to Main Content

I have two components parent and child,in child i have the text area, which onchange will reset my initial value.
On keeping onchange attribute in the textarea , the default value is being removed
Initially it should show default value, upon changing it should change the text.

Parent

const Main = () => {

    const notes = [
        {id:1,
         title:"What is React? ",
        content:"React is a JavaScript library that aims to simplify development of visual interfaces.",
        // date:"28/04/2023"
        },
        {
         id:2,
         title:"What is Java?",
         content:"Java is a most popular, object-oriented, widely used programming language and platform that is utilized for Android development, web development, artificial intelligence, cloud applications, and much more.",
        //  date:"28/04/2023"
        }
    ]
    const [mynote, setNote] = useState(notes);
    const [isActive,setisActive] = useState([]);
  
    const handleClick = (id) =>{
       setisActive(id);
    }

    const pullcontent = (id,plnote) =>{
      console.log("pull Content for->"+id+"..."+plnote);
      setNote(mynote.map(obj =>{
        if( obj['id'] === parseInt(id)){
          return {...obj,content:plnote}
        }else{
          return obj;
        }
      }));
    }

  return (
    <div className='main'>
    <div className="rightnote note-cont">
      <div className="contents">
      {
        mynote.map((obj)=>{
            return (
         <div className={`conts ${isActive === obj.id ? 'cont-active':'cont-inactive'}`} key={obj.id}>
                <div className="con">
                <Content notecontent = {obj.content} noteid={obj.id} onCh={(pullednote) => pullcontent(obj.id,pullednote)}/>
                </div>
             </div>
            )
        })
      }
      </div> 
        </div>

    </div>
  )
}

export default Main

Child

import React, { useState } from 'react';
import './Content.css';

const Content = (Props,{notecontent,noteid}) => {

  const [note,setnote] = useState(notecontent);

  const changeHandler = (e) =>{
    setnote(e.target.value);
    Props.onCh(note);
  }

  return (
    <div className="content">
      <textarea name="" id={noteid}  defaultValue={notecontent} cols="164" rows="48" contentEditable={true} onChange={(e)=>changeHandler(e)} suppressContentEditableWarning={true}/>
      </div>
  )
}

export default Content;  

Please Suggest me something

3

Answers


  1. Your code seems to be working if you make these small changes:

    // const Content = (Props,{notecontent,noteid}) => { // BEFORE:
    const Content = ({onCh, notecontent,noteid}) => { 
    
      const [note,setnote] = useState(notecontent);
    
      const changeHandler = (e) =>{
        setnote(e.target.value);
        onCh(note); // <-- Props.onCh() -> onCh()
      }
    
    Login or Signup to reply.
  2. First change this

    const Content = (Props,{notecontent,noteid}) => {

    to

    const Content = ({onCh,notecontent,noteid}) => {

    After this your typed text will be one character less

    This happens because you are using setnote and then passing the note value right after it.

    The way react works is that when you have setState calls inside a function the value is only updated when the function has finished execution.
    So in this case

    const changeHandler = (e) =>{
        setnote(e.target.value);
        onCh(note);
        // The value of the note is not set here when you pass it
    }
    // After this function has finished execution then it is passed
    

    There are 2 solutions to this

    1. Just pass the e.target.value to the Props.onCh function
    const changeHandler = (e) =>{
        setnote(e.target.value);
        onCh(e.target.value);
    }
    
    1. use flushSync
    import { flushSync } from 'react-dom';
    
    ...
    
    const changeHandler = (e) =>{
        flushSync(()=>{
        setnote(e.target.value);
        onCh(note);
        })
    }
    

    But, I would recommend the first way as flushSync is performance heavy.

    Login or Signup to reply.
  3. import React, { useState } from 'react';
    import './Content.css';
    
    const Content = (Props,{notecontent,noteid}) => {
    
      const [note,setnote] = useState(notecontent);
    
      const changeHandler = (e) =>{
        setnote(e.target.value);
        Props.onCh(note);
      }
    
      return (
        <div className="content">
          <textarea name="" id={noteid}  defaultValue={notecontent} cols="164" rows="48" contentEditable={true} value={note} onChange={(e)=>changeHandler(e)} suppressContentEditableWarning={true}/>
          </div>
      )
    }
    
    export default Content;  
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search