Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

189
Vistas
How to prevent setting a state variable to another state variable?

I have a controlled component that I call Note. I want its default value to be equal to the selected note (which is set in App.js and passed through as a prop). It seems redundant/bad practice. Here's my code, simplified to the relevant parts. How can I set the default value of textarea to be equal to another state variable?

Edit: Forgot to mention that selectedNote is changed in another component. It works for the state set in useEffect but not for the updates.

App.js

function App(){
  const [selectedNote, setSelectedNote] = useState("")
    
  useEffect(() => {
    async function fetchData(){
      let req = await fetch("http://localhost:9292/notes");
      let res = await req.json();
      setSelectedNote(res[0])
    }
    fetchData()
  },[])

  return (
    <Note selectedNote={selectedNote.body}/>
  )
}

Note.js

function Note({selectedNote}) {
  const [editValue, setEditValue] = useState(selectedNote)

  return (
    <form>
      <textarea value={editValue} onChange={handleChange}>
      </textarea>
    </form>
  )
}

(To clarify, I have no issues if I write const [editValue, setEditValue] = useState("testing123") or some other string)

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

So ideally you want to lift state up so that the parent component manages the state updates, and the Notes component is as dumb as possible.

In this example the data is loaded into state, and then the notes are built, only receiving an id, some body text which will be their value, and an onChange handler.

When the text is changed, the state is copied, the object in the array (defined by the id) updated, and the new array pushed back into state.

const { useEffect, useState } = React;

const json = '[{"id":1,"body":"Note1"},{"id":2,"body":"Note2"},{"id":3,"body":"Note3"}]';

function mockApi() {
  return new Promise(res => {
    setTimeout(() => res(json), 2000);
  });
}

function Example() {

  const [ notes, setNotes ] = useState([]);
  const [ selectedNote, setSelectedNote ] = useState(null);

  useEffect(() => {
    mockApi()
      .then(res => JSON.parse(res))
      .then(data => setNotes(data));
  }, []);

  function handleChange(e) {
    const { value, dataset: { id } } = e.target;
    const copy = [...notes];
    copy[id - 1].body = value;
    setNotes(copy);
  }
  
  function handleClick() {
    console.log(JSON.stringify(notes));
  }
  
  if (!notes.length) return 'Loading';

  return (
    <div>
      {notes.map(note => {
        return (
          <Note
            key={note.id}
            id={note.id}
            body={note.body}
            handleChange={handleChange}
          />
        )
      })}
      <button onClick={handleClick}>
        View state
      </button>
    </div>
  );

}

function Note({ id, body, handleChange }) {
  return (
    <textarea
      data-id={id}
      value={body}
      onChange={handleChange}
    />
  );
}

ReactDOM.render(
  <Example />,
  document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

about 4 years ago · Juan Pablo Isaza Denunciar

0

You can provide a function to useState that will only be invoked once, when the component renders. Use that function to copy the prop value into the Note's private state.

const [editValue, setEditValue] = useState(() => selectedNote)

You may have other problems, such as the prop value being blank on initial render, but this is still usually the most straightforward way to initialize a private state var based on a prop.

If it turns out that blank-initial-state is an insurmountable problem, then you may instead need to set up a useEffect that updates the private state when the prop value changes to a satisfactory value. Something like this:

const [editValue, setEditValue] = useState()
React.useEffect(() => {
    // only update state if old is blank & new is not
    if(!editValue && selectedNote) setEditValue(selectedNote)
}, [selectedNote])
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda