фильтровать данные, полученные с помощью redux

#reactjs #redux #react-hooks

#reactjs #redux #реагировать-перехваты

Вопрос:

как вы можете видеть из моего кода, у меня есть некоторые реквизиты ({allRecipes}), полученные с помощью Redux, я могу отобразить их const mapRecipe =() , но я хотел бы отфильтровать их с помощью строки поиска, я думаю, что решением будет эффект использования крючка, но я не могу продолжать,

 useEffect(() =>{
      
    const res = allRecipies.filter(el => el.name.toLowerCase().includes(searchTerm))
    setSearchResults(res)},[searchTerm])

 

выдает мне ошибку: allRecipies равно нулю.

надеюсь, кто-нибудь может указать мне правильное направление. здесь код:

     const [searchTerm, setSearchTerm] = useState("");
    const [searchResults, setSearchResults] = useState([]);
    const handleChange = event => {
        console.log("search bar",event.target.value)

        setSearchTerm(event.target.value);
    }
    useEffect(() =>{
      
    const res = allRecipies.filter(el => el.name.toLowerCase().includes(searchTerm))
    setSearchResults(res)
},[searchTerm])
 const mapRecipe =() =>{
     if(!allRecipies){return<li>no fish</li>}
     else{return allRecipies.map(el =>{
     return (<div className="col s12 l4" key={el._id}  >
   
            
                
                
                    <div className="card ">
                      <div style={{backgroundImage:`url(${staticImage})`,height:"200px",backgroundSize:"cover"}} className="card-image ">
                     
                      <a className="btn-floating halfway-fab waves-effect waves-light btn-large lime darken-2"><i className="material-icons">clear</i></a>
                      </div>
                     
                       
                            <span className="card-title">{el.name}</span>
                            
                            
                        
                        <div className="card-content">
                            <p>{el.listOfStages[0]}</p>
                        </div>
                    </div>
              
            

    
     </div>)
     })}
 
} 
 return (
    <div>
        <input type="text"
         placeholder="search"
         value={searchTerm}
         onChange={handleChange}/>
    <div className="row" >
        {mapRecipe()}
          
    </div>
   
    </div>
  
      
 )
 
    
 }
function mapStateToProps(state){
    console.log(state);
    return state
}
export default connect(mapStateToProps)(Landing) 
 

Комментарии:

1. Ketan я пробовал ваше решение, но продолжаю давать мне это; Ошибка типа: не удается прочитать свойство ‘filter’ из null

2. res = allRecipies?.filter(el => el.name.toLowerCase().includes(searchTerm.trim().toLowerCase()))

3. да, поэтому, если я console.log(allRecipies), я получил результат дважды, первый равен нулю, а второй заполнен

4. и поиск работает сейчас? и нулевой ошибки больше нет?

5. я думаю, что проблема для этого та же const mapRecipe =() =>{ if(!allRecipies){return<li>no fish</li>} else{return allRecipies.map(el =>{ return (<div className="col s12 l4" key={el._id} > , я использовал условный оператор, потому что в первый раз allRecipes пуст, вы согласны?

Ответ №1:

Используйте распространение null, чтобы избавиться от этой ошибки:

 useEffect(() =>{
    const res = allRecipies?.filter(el => el.name.toLowerCase().includes(searchTerm))
    setSearchResults(res)
},[searchTerm])

 

Подробнее об этом можно прочитать здесь: Оператор распространения Null в JavaScript

Ответ №2:

Я бы сделал это:-

  1. обнаруживать входящие allRecipies с useEffect помощью и применять default searchTerm :-
  2. еще useEffect один для фильтрации searchTerm :-
 // do search
const seacrh = (allRecipies, searchTerm) => {
  return allRecipies.filter(el => el.name.toLowerCase().includes(searchTerm))
}

// run when 'allRecipies' present
useEffect(() => {
  (() => {
    if(allRecipes) {
      setSearchResult(() => search(allRecipies, ''))
    }
  })()
}, [allRecipies])

// run when there's changes on 'searchTerm'
useEffect(() => {
  (() => {
    if(searchTerm) {
      setSearchResult(() => search(allRecipies, searchTerm))
    }
  })()
}, [searchTerm])