Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

190
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda