Home > Blockchain >  How to return to original state in ReactJs when not data found
How to return to original state in ReactJs when not data found

Time:06-19

I'm currently fetching data from my db but for the simplicity of this Q, I have decided to manually create an example with fake data.

I'm building a search-bar for my users to look through all of the data coming from db and everything seems to be working fine when looking for a specific document, however, I want to reset the state to its original data when the input is empty.

This is what I've tried so far but with no success. Am I missing something?

const objects = [
  {
    _id: 0,
    title: 'Title One',
  },
  {
    _id: 1,
    title: 'Title Two',
  },
  {
    _id: 2,
    title: 'Title Three',
  },
]

const [keyword, setKeyword] = useState('')
const [list, setList] = useState([]);

useEffect(() => {
    setList(objects);
}, [objects]);

const handleChange = () => (e) => {
  e.preventDefault()
  setKeyword(e.target.value)

  if (keyword !== '') {
    const result = objects.filter((object) => {
      return object.title.toLowerCase().startsWith(keyword.toLowerCase())
    })
    setList(result)
  } else {
    // THIS IS WHERE THE PROBLEM RESIDES...
    console.log('Original data')
    setList(objects)
  }
}

This is the current output: My application output

CodePudding user response:

What you're doing wrong is in these lines

setKeyword(e.target.value)

if (keyword !== '') {

The state is updated asynchronously, and the value of the keyword will be old.

What you can do is update the state in handleChange and then have a separate useEffect to update the results:

const [keyword, setKeyword] = useState('')
const [list, setList] = useState([]);

useEffect(() => {
    setList(objects);
}, [objects]);

useEffect(() => {
  if (keyword !== '') {
    const result = objects.filter((object) => {
      return object.title.toLowerCase().startsWith(keyword.toLowerCase())
    })
    setList(result)
  } else {
    // THIS IS WHERE THE PROBLEM RESIDES...
    console.log('Original data')
    setList(objects)
  }
}, [keyword]);

const handleChange = () => (e) => {
  e.preventDefault()
  setKeyword(e.target.value)
}

CodePudding user response:

State setters are asynchronous. The code following a state update (your if(keyword) may be run before the state update is complete (setKeyword)

Your code may be simplified if you merge keyword & list in a single object.

var [searchState, setSearchState] = useState({keyword: '', list: objects.slice());


handleChange=(evt)=>{
    let word = evt.target.value;
    let wordLower= word.toLowerCase();
    setSearchState({
        keyword:word,
        list: word?objects.filter(o=>o.title.toLowerCase().startsWith(wordLowerCase):objects.slice()
    });
};

Or you can use class based component where the state is a single object.

  • Related