0

I am trying to list the query state that a user types in an input box. The problem I am facing here is the value is 1 behind the original. I believe it might be bcoz of the async behavior of the query state that I formed using useState and setQuery method which is updating the query(Correct me if my guess is wrong).

Let me know how can I fix this problem.

let queryList = [];

function App() {
  const [query, setQuery] = React.useState("");

  const handleChange = e => {
    setQuery(e.target.value);
    queryList.push(query);
    console.log(query);
  };
  return (
    <div className="App">
      <h1>Hello React</h1>
      <input type="text" value={query} onChange={handleChange} />
      <div className="query">
        {queryList.map((x, id) => (
          <li key={id}>{x}</li>
        ))}
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <App />
  rootElement
);
<script src="https://unpkg.com/react@16.8.6/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.8.1/umd/react-dom.production.min.js"></script>

<div id="root"></div>

Working CodeSandbox Link - https://codesandbox.io/s/tender-mountain-qzgxf

Also, I need one help regarding setting up react code in stack snippets. I added here but its not working let me know what I am doing wrong. Thanks in advance. :)

Nesh
  • 2,389
  • 7
  • 33
  • 54
  • Check this answer https://stackoverflow.com/questions/62846824/react-select-onchange-returning-previous-value-instead-of-current/62846909#62846909 – Rohan Agarwal Jul 18 '20 at 11:42
  • Rather than doing `queryList.push(query)` you can do `queryList.push(e.target.value)` ? – swapnesh Jul 18 '20 at 11:43

2 Answers2

2

I think queryList should be manages as state here.

Working code in SO Snippet

function App() {
  const [query, setQuery] = React.useState("");
  const [queryList, setQueryList] = React.useState([]);
  const handleChange = (e) => {
    setQuery(e.target.value);
    setQueryList([...queryList, e.target.value]);
  };
  return (
    <div className="App">
      <h1>Hello React</h1>
      <input type="text" value={query} onChange={handleChange} />
      <div className="query">
        {queryList.map((x, id) => (
          <li key={id}>{x}</li>
        ))}
      </div>
    </div>
  );
}

class Root extends React.Component {
  render() {
    return (
      <App/>
    );
  }
}

ReactDOM.render(<Root />, document.getElementById('root'));
<script src="https://unpkg.com/react@16.8.6/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.8.1/umd/react-dom.production.min.js"></script>

<div id="root"></div>

Good news

I've already made a create-react-app template in stack snippets here in MSO post

Feel free to edit and improve it

glinda93
  • 7,659
  • 5
  • 40
  • 78
1

You always push the current state in time of event, instead push the value of the event:

const handleChange = (e) => {
  const newQuery = e.target.value;
  queryList.push(newQuery);
  setQuery(newQuery);
};

Edit angry-greider-s7hp0

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118