Javascript Can';t使用文本输入值更新反应状态

Javascript Can';t使用文本输入值更新反应状态,javascript,reactjs,react-hooks,state,Javascript,Reactjs,React Hooks,State,我想做的是从API中获取员工列表,将他们保存在状态中,然后按员工姓名进行“实时”搜索 我挣扎的地方是我不能用过滤数组更新我的状态。当我开始在搜索栏中输入时,员工会进行筛选,但一旦我删除了一些字母,一切都不会改变 若I.map()不是state,而是包含过滤数组的变量,则一切正常。这在某种程度上与状态和状态更新有关 这是我的密码: 导入“/App.css”; 从“React”导入React,{useState,useffect}; 从“样式化组件”导入样式化; const Container=st

我想做的是从API中获取员工列表,将他们保存在状态中,然后按员工姓名进行“实时”搜索

我挣扎的地方是我不能用过滤数组更新我的状态。当我开始在搜索栏中输入时,员工会进行筛选,但一旦我删除了一些字母,一切都不会改变

若I.map()不是state,而是包含过滤数组的变量,则一切正常。这在某种程度上与状态和状态更新有关

这是我的密码:

导入“/App.css”; 从“React”导入React,{useState,useffect}; 从“样式化组件”导入样式化; const Container=styled.div` 宽度:1280px; 最大宽度:100%; 保证金:0自动; th{ 文本对齐:左对齐; 填充:10px; 背景:#f5; 光标:指针; :悬停{ 背景:ddd; } } 运输署{ 边框底部:1px实心#F5; 填充物:5px; } `; const TopHeader=styled.div` 显示器:flex; 证明内容:之间的空间; 填充:20px; 输入{ 宽度:400px; 填充:10px; } `; 函数App(){ const[employees,updateEmployees]=useState([]); 如果(员工==0){ document.title=“加载…”; } useffect(()=>{ 取回(“http://dummy.restapiexample.com/api/v1/employees") .then(res=>res.json()) 。然后(结果=>{ 更新员工(result.data); document.title=`Total:${result.data.length}`; }); }, []); 常量[searchValue,updateSearch]=useState(“”); const filteredEmpl=employees.filter(empl=>{ 返回employee_name.toLowerCase().includes(searchValue.toLowerCase()); }); 常量handleSearch=e=>{ 更新搜索(如目标值); 更新员工(筛选员工); }; 返回( 员工总数:{employees.length}已筛选 员工:{filteredEmpl.length} 身份证件 员工姓名 员工工资 员工年龄 {employees.map(employeer=>( {employee.id} {employee.employee_name} {employee.employee_salary} {employee.employee_age} ))} ); } 导出默认应用程序;
你知道缺少什么吗?

问题是这里的搜索词过时了

const handleSearch=e=>{
更新搜索(如目标值);
更新员工(筛选员工);
};
调用
updateEmployees
时。每次搜索时,您还将替换从api调用获得的结果。无需将搜索词设置为state,请改为:

const[searchResult,updateSearch]=useState([]);
const filterEmpl=useCallback((搜索术语)=>{
返回employees.filter({employeen\u name})=>{
返回employee_name.toLowerCase().includes(searchTerm.toLowerCase());
})
}[雇员];
const handleSearch=useCallback({target})=>{
常量filteredEmpl=filterEmpl(target.value)
更新搜索(filteredEmpl);
},[FilterEmple]);

您不需要将筛选的员工存储到状态变量中。每次更新
searchValue
employees
时(通过使用
usemo
),您只需要从原始员工计算它

顺便说一句,最好像上面那样将标题管理成其自身的效果

const [employees, updateEmployees] = useState([]);
const [searchValue, updateSearch] = useState("");

useEffect(() => {
  fetch("http://dummy.restapiexample.com/api/v1/employees")
    .then(res => res.json())
    .then(result => updateEmployees(result.data));
}, []);

useEffect(() {
  document.title = !employees.length ? "Loading..." : `Total: ${employees.length} `
}, [employees]);

const filteredEmpl = useMemo(() => {
   if (!searchValue) return employees;

   return employees.filter(empl => 
       empl.employee_name.toLowerCase().includes(searchValue.toLowerCase())
   );
}, [employees, searchValue]);

const handleSearch = e => updateSearch(e.target.value);
如果要对员工数组进行排序,可以这样做

const filteredEmpl = useMemo(() => {
   const sortFn = (empl1, empl2) => {...};
   const filterFn = empl => 
     empl.employee_name.toLowerCase().includes(searchValue.toLowerCase());

   if (!searchValue) {
     return [...employees].sort(sortFn);
   } else {
     return employees.filter(filterFn).sort(sortFn);
   }
}, [employees, searchValue]);

如果排序条件可以由用户(通过输入)更新,则需要将排序条件存储到新的状态变量中。

我通过更改两个变量名对代码进行了一些调整,并添加了一个筛选函数。我希望这有帮助。如果您在这个问题上需要任何进一步的帮助,请告诉我。干杯

import React, { useState, useEffect } from "react";
import styled from "styled-components";

import "./App.css";

const Container = styled.div`
  width: 1280px;
  max-width: 100%;
  margin: 0 auto;
  th {
    text-align: left;
    padding: 10px;
    background: #f5f5f5;
    cursor: pointer;
    :hover {
      background: #ddd;
    }
  }
  td {
    border-bottom: 1px solid #f5f5f5;
    padding: 5px;
  }
`;

const TopHeader = styled.div`
  display: flex;
  justify-content: space-between;
  padding: 20px;
  input {
    width: 400px;
    padding: 10px;
  }
`;

const Loading = styled.div`
  display: flex;
  text-align: 'center';
  padding: 20px;
  font-size: 2em;
  font-weight: 300;
`;

const App = () => {
    const [employees, setEmployees] = useState([]); // Change variable name from updateEmployees to setEmployees
    const [searchValue, setSearchValue] = useState(""); // changed variable name from updateSearch to setSearchValue
    const [employeesTotal, setEmployeesTotal] = useState(0); // Add a new state to handle intial employees total

    // Renamed employees variable to employeesTotal
    if (employeesTotal) {
        document.title = "Loading...";
    }

    useEffect(() => {
        fetch("http://dummy.restapiexample.com/api/v1/employees")
            .then(res => res.json())
            .then(result => {
                setEmployees(result.data);
                setEmployeesLength(result.data.length);
                document.title = `Total: ${result.data.length} `; // Why though?
            });
    }, []);

    const handleSearch = e => {
        setSearchValue(e.target.value);
    };

    const filterDocument = doc => {
        const employeeName = doc.employee_name.toLowerCase() || '';
        return employeeName.includes(searchValue.toLowerCase());
    };

    // Check if employees array contains data, if it does, display content, otherwise show loading
    return (
            employeesTotal ? (
                <Container>
                    <TopHeader>
                        <div>
                            Total employees: <strong>{employeesTotal}</strong> Filtered employees: <strong>{employees.length}</strong>
                        </div>
                        <div>
                            <input
                                type="text"
                                onChange={handleSearch}
                                value={searchValue}
                                placeholder="search"
                            />
                        </div>
                    </TopHeader>

                    <table style={{ width: "100%" }}>
                        <thead>
                            <tr>
                                <th>id</th>
                                <th>Employee name</th>
                                <th>Employee salary</th>
                                <th>Employee age</th>
                            </tr>
                        </thead>
                        <tbody>
                            {/** Add filterDocument to filter function on employee array before calling its map funtion */}
                            {employees.filter(filterDocument).map(employee => (
                                <tr key={employee.id}>
                                    <td>{employee.id}</td>
                                    <td>{employee.employee_name}</td>
                                    <td>{employee.employee_salary}</td>
                                    <td>{employee.employee_age}</td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </Container>
            ) : (
                    <Loading>Loading...</Loading>
                )
    );
}

export default App;
import React,{useState,useffect}来自“React”;
从“样式化组件”导入样式化;
导入“/App.css”;
const Container=styled.div`
宽度:1280px;
最大宽度:100%;
保证金:0自动;
th{
文本对齐:左对齐;
填充:10px;
背景:#f5;
光标:指针;
:悬停{
背景:ddd;
}
}
运输署{
边框底部:1px实心#F5;
填充物:5px;
}
`;
const TopHeader=styled.div`
显示器:flex;
证明内容:之间的空间;
填充:20px;
输入{
宽度:400px;
填充:10px;
}
`;
常量加载=styled.div`
显示器:flex;
文本对齐:“居中”;
填充:20px;
字号:2em;
字体大小:300;
`;
常量应用=()=>{
const[employees,setEmployees]=useState([]);//将变量名从updateEmployees更改为setEmployees
const[searchValue,setSearchValue]=useState(“”;//将变量名从updateSearch更改为setSearchValue
const[employeesTotal,setEmployeesTotal]=useState(0);//添加新状态以处理初始员工总数
//将employeesTotal变量重命名为employeesTotal
if(雇员总数){
document.title=“加载…”;
}
useffect(()=>{
取回(“http://dummy.restapiexample.com/api/v1/employees")
.then(res=>res.json())
。然后(结果=>{
setEmployees(结果数据);
setEmployeesLength(result.data.length);
document.title=`Total:${result.data.length}`;//为什么?
});
}, []);
常量handleSearch=e=>{
设置搜索值(如目标值);
};
常量过滤器文档=doc=>{
const employeeName=doc.employee_name.toLowerCase()| |“”;
return employeeName.includes(searchValue.toLowerCase());
};
//检查employees数组是否包含数据,如果包含,则显示内容,否则显示加载
返回(
雇员总数(