Reactjs 不更新功能组件中的状态

时间:2021-04-27 18:49:48

标签: javascript reactjs react-hooks react-functional-component react-state

我正在用 reactS 开发一个简单的应用程序。该应用程序的主要目的是显示一些卡片,在搜索时,卡片将被过滤并显示选择性卡片。我正在分享 App.js 的代码。 我有一个文件名“Robots.js”

import './App.css';
import CardList from './Components/CardList';
import Header from './Components/Header';
import {Robots} from './Components/Robots';

function App() {

  const [robots,setRobots] = useState({
    robo:Robots,
    search:''
  });

  const onSearchChange = (e) =>{
    setRobots({...robots,search:e.target.value});
    const filteredRobots = robots.robo.filter(item=>{return item.name.toLowerCase().includes(robots.search.toLowerCase())});
    //setRobots({...robots,robo:filteredRobots});
    console.log(filteredRobots);
  }

  return (
    <div>
      <Header onSearchChange={onSearchChange} />
      <CardList Robots={robots.robo}/>
    </div>
  );
}

export default App;

如果我评论 setRobots({...robots,robo:filteredRobots}); 控制台上的这一行我可以显示数组正在减少它的项目数量,但使用该行它什么都不做。我认为它应该这样做是有道理的。 我希望我说清楚了。

2 个答案:

答案 0 :(得分:1)

可以一键更新状态,如下图:

const onSearchChange = (e) => {

  const filteredRobots = robots.robo.filter(item => {
    return item.name.toLowerCase().includes(robots.search.toLowerCase())
  });

  console.log(filteredRobots);

  setRobots({
    robo: filteredRobots,
    search: e.target.value
  });

}

由于您只有两个属性,因此您可以使用这些属性创建一个新对象,而实际上并不需要展开运算符。

答案 1 :(得分:0)

setRobots 运行“异步” - 因此,如果您有:

const[data, setData] = setState(5);

const update = (newData) => {
   setData(1);
   console.log(data) // will print 5
}

并且只有在第二次渲染时它才会打印 1

您可以在此处阅读更多信息:https://reactjs.org/docs/state-and-lifecycle.html

在你的实现中你有一个问题,你没有保存卡片的原始数组

所以先保存原数组

// Here will be the full list of cards.
const [cards, setCards] = useState(allCards);

// Here will be the search by text
const [search, setSearch] = useState("");

// Here will be all the filtered cards
// If you don't know whats useMemo is you can look in here: https://reactjs.org/docs/hooks-reference.html#usememo
const filteredCards = useMemo(()=>{
   return cards.filter((card) => 
      card.item.toLowerCase().contains(search.toLowerCase()));

},[cards, search])

// on search changed callback 
const onSearchChange = (e)=>{setSearch(e.target.value || '')}

// then return your component 
  return (
    <div>
      <Header onSearchChange={onSearchChange} />
      <CardList Robots={filteredCards}/>
    </div>
  );