重新渲染后如何保存组件状态?反应 js

How to save a component state after re-rendering? React js

有一些电影卡片,客户可以点击它们,它们的颜色会变成灰色并带有模糊效果,这意味着电影被选中了。 同时,电影id被传送到一个数组列表中。在搜索栏中,你可以搜索你最喜欢的电影,但问题是在你在输入区域输入内容后,灰色的电影卡失去了它们的风格(我想是因为它们被删除并根据我的代码再次呈现)但是array 部分运行良好,它们仍在 array 列表中。 我怎样才能保持他们的风格?

搜索页面:

export default function Index(data) {
  const info = data.data.body.result;
  const [selectedList, setSelectedList] = useState([]);
  const [searchTerm, setSearchTerm] = useState('');

  return (
    <>
      <main className={parentstyle.main_container}>
        <NavBar />
        <div className={style.searchbar_container}>
          <CustomSearch
            onChange={(e) => {
              setSearchTerm(e.target.value);
            }}
          />
        </div>
        <div className={style.card_container}>
          {info
            .filter((value) => {
              if (searchTerm === '') {
                return value;
              } else if (
                value.name
                  .toLocaleLowerCase()
                  .includes(searchTerm.toLocaleLowerCase())
              ) {
                return value;
              }
            })
            .map((value, key) => {
              return (
                <MovieCard
                  movieName={value.name}
                  key={key}
                  movieId={value._id}
                  selected={selectedList}
                  setSelected={setSelectedList}
                  isSelected={false}
                />
              );
            })}
        </div>
        <div>
          <h3 className={style.test}>{selectedList}</h3>
        </div>
      </main>

电影卡片组件:

export default function Index({ selected, movieName, movieId, setSelected }) {
  const [isActive, setActive] = useState(false);

  const toggleClass = () => {
    setActive(!isActive);
  };

  useEffect(()=>{

    
  })

  const pushToSelected = (e) => {
    if (selected.includes(e.target.id)) {
      selected.splice(selected.indexOf(e.target.id), 1);

      console.log(selected);
    } else {
      selected.push(e.target.id);

      console.log(selected);
      console.log(e.target);
    }
    setSelected([...selected]);
    toggleClass();
  };

  return (
    <div>
      <img
        className={isActive ? style.movie_selected : style.movie}
        id={movieId}
        name={movieName}
        src={`images/movies/${movieName}.jpg`}
        alt={movieName}
        onClick={pushToSelected}
      />
      <h3 className={style.title}>{movieName}</h3>
    </div>
  );
}

这是一个非常宽泛的话题。你能做的最好的事情就是查找“React state management”。 与 React 生态系统中的所有内容一样,它可以由各种不同的库处理。 但是对于最新版本的 React,您可以首先检查内置工具: 查看状态生命周期:https://reactjs.org/docs/state-and-lifecycle.html (我在您的示例中看到您正在使用 useState 挂钩,但我添加这些挂钩是为了对需要它的人进行更结构化的解释)

那你可能想看看状态相关的钩子比如useState: https://reactjs.org/docs/hooks-state.html

useEffect(与 useState 一起使用): https://reactjs.org/docs/hooks-effect.html

并使用上下文: https://reactjs.org/docs/hooks-reference.html#usecontext

对于内置工具集之外的东西,有许多流行的状态管理库也可以与 React 一起使用,其中最受欢迎的是:Redux、React-query、Mobx、Recoil、Flux、Hook-state。请记住,您应该使用什么取决于您的用例和需求。这些还可以帮助您不仅在重新渲染之间而且在应用程序刷新之间保持您的状态。每天都有越来越多的图书馆出现。

这是一篇不错的文章,包含更多信息: https://dev.to/workshub/state-management-battle-in-react-2021-hooks-redux-and-recoil-2am0#:~:text=State%20management%20is%20simply%20a,you%20can%20read%20and%20write.&text=When%20a%20user%20performs%20an,occur%20in%20the%20component's%20state.

我无法直接测试您的代码,所以我假设这就是问题所在:

  1. 不要直接转换状态 (splice/push) - 总是创建一个克隆或其他东西。
  2. 使 setActive 基于列表而不是依赖。 (这是样式被删除的真正问题)

试试这个:

  const pushToSelected = (e) => {
    if (selected.includes(e.target.id)) {
      
      // filter out the id
      setSelected(selected.filter(s => s !== e.target.id));
      return;
    }
    
    // add the id
    setSelected([...selected, e.target.id]);
  };

  // you may use useMemo here. up to you.
  const isActive = selected.includes(movieId);

  return (
    <div>
      <img
        className={isActive ? style.movie_selected : style.movie}
        id={movieId}
        name={movieName}
        src={`images/movies/${movieName}.jpg`}
        alt={movieName}
        onClick={pushToSelected}
      />
      <h3 className={style.title}>{movieName}</h3>
    </div>
  );