过滤时反应丢失检查

问题描述

我不知道如何将“活动”添加用户状态中。 为了在此处发布此内容,我对该州的一些用户进行了硬编码,但他们应该是从 API 中获取的 - 而这并没有带有“活动”。我需要能够标记复选框,以便特定用户变为活动状态, 如果活动 - 通过文本输入在列表中进行搜索时必须保持活动状态,因此它不会重置。根据我写的内容,我对 user.active 没有定义。有什么建议吗?

App.js

import './App.css';
import UserList from './components/UserList';
import './style/style.css';

function App() {
  return (
    <div className="App">
      <UserList />
    </div>
  );
}

export default App;

UserList.js


import React,{ useState,useEffect } from 'react';

function UserList() {
  const [users,setUsers] = useState([
    {
      id: 681,first_name: 'James',last_name: 'Smith',email: 'example1',gender: 'm',},{
      id: 3123,first_name: 'Richard',last_name: 'Greene',email: 'example2',{
      id: 512,first_name: 'Denise',last_name: 'Bank',email: 'example3',gender: 'f',{
      id: 654,first_name: 'Carl',last_name: 'Ross',email: 'example4',]);
  const [search,setSearch] = useState('');
  const [filteredUsers,setFilteredUsers] = useState();
  const [checkedUsers,setCheckedUsers] = useState('');

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        const result = await fetch(users);
        result.sort(function (a,b) {
          if (a.last_name.toLowerCase() < b.last_name.toLowerCase()) return -1;
          if (a.last_name.toLowerCase() > b.last_name.toLowerCase()) return 1;
          else return;
        });
        setUsers(result);
      } catch (error) {
        console.log(error);
      }
    };
    fetchUsers();
  },[]);

  useEffect(() => {
    setFilteredUsers(
      users.filter(
        (user) =>
          user.first_name.toLowerCase().includes(search.toLowerCase()) ||
          user.last_name.toLowerCase().includes(search.toLowerCase())
      )
    );
  },[users,search]);

  useEffect(() => {
    setCheckedUsers(users.filter((user) => user.active));
  },[users]);

  const changeChecked = (id) => {
    users.forEach((user) => {
      if (user.id === id) {
        console.log(user);
        if (user.active === '') {
          user.active = true;
        } else user.active = false;
      }
    });
    setUsers(users);
    console.log(checkedUsers);
  };

  return (
    <div className="list-container">
      <div className="search">
        <input
          type="text"
          placeholder="Search for users"
          onChange={(event) => setSearch(event.target.value)}
        />
      </div>
      {filteredUsers &&
        filteredUsers.map((user) => (
          <div
            className="user-block"
            key={user.id}
            onClick={() => console.log(user.id,user.active)}>
            <div className="details">
              <h5>
                {user.first_name} {user.last_name}
              </h5>
              <p>{user.email}</p>
            </div>
            <input
              type="checkBox"
              checked={user.active}
              onClick={(event) => changeChecked(user.id)}
            />
          </div>
        ))}
    </div>
  );
}

export default UserList;

解决方法

这里有几点:

  1. 我认为您应该在获取后映射用户以添加具有默认值的活动,因此在任何情况下都不是未定义的:

    useEffect(() => {
        const fetchUsers = async () => {
          try {
            const request = await fetch(users);
            const response = request.map(data => ({...data,active: true})).sort(function (a,b) {
              if (a.last_name.toLowerCase() < b.last_name.toLowerCase()) return -1;
              if (a.last_name.toLowerCase() > b.last_name.toLowerCase()) return 1;
              else return;
            });
            setUsers(response);
          } catch (error) {
            console.log(error);
          }
        };
        fetchUsers();
      },[]);
    
  2. 你过滤的用户绝对没用,你可以用用户本身来做,完全失去 useEffect 和状态变量:

    users.filter(user =>
              user.first_name.toLowerCase().includes(search.toLowerCase()) ||
              user.last_name.toLowerCase().includes(search.toLowerCase())
          ).map((user) => (
              <div
                className="user-block"
                key={user.id}
                onClick={() => console.log(user.id,user.active)}>
                <div className="details">
                  <h5>
                    {user.first_name} {user.last_name}
                  </h5>
                  <p>{user.email}</p>
                </div>
                <input
                  type="checkbox"
                  checked={user.active}
                  onClick={(event) => changeChecked(user.id)}
                />
              </div>
            )
    
  3. 最后但并非最不重要的一点是,您的 changeChecked 函数正在改变数组。我也会使用 .map 而不是 forEach:

    const changeChecked = (id) => {
      setUsers(
        users.map(user => {
          if (user.id === id) {
            return {
               ...user,active: !user.active
            };
          } else {
             return user;
          }
        })
      );
        console.log(checkedUsers);
    };
    

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...