javascript - 无法使用文本输入值更新 React 状态
问题描述
我想要做的是我想从 API 获取员工列表,将它们保存在状态中,并按员工姓名进行“实时”搜索。
我挣扎的地方是我无法用过滤数组更新我的状态。当我开始在搜索字段中输入时,员工会过滤,但是一旦我删除了一些字母,什么都没有改变。
如果我 .map() 不是状态,而是包含过滤数组的变量,那么一切正常。这在某种程度上与状态和状态更新有关。
这是我的代码:
import "./App.css";
import React, { useState, useEffect } from "react";
import styled from "styled-components";
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;
}
`;
function App() {
const [employees, updateEmployees] = useState([]);
if (employees == 0) {
document.title = "Loading...";
}
useEffect(() => {
fetch("http://dummy.restapiexample.com/api/v1/employees")
.then(res => res.json())
.then(result => {
updateEmployees(result.data);
document.title = `Total: ${result.data.length} `;
});
}, []);
const [searchValue, updateSearch] = useState("");
const filteredEmpl = employees.filter(empl => {
return empl.employee_name.toLowerCase().includes(searchValue.toLowerCase());
});
const handleSearch = e => {
updateSearch(e.target.value);
updateEmployees(filteredEmpl);
};
return (
<Container>
<TopHeader>
<div>
Total employees: <strong>{employees.length}</strong> Filtered
employees: <strong>{filteredEmpl.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>
{employees.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>
);
}
export default App;
任何想法缺少什么?
解决方案
我通过更改几个变量名称并添加了过滤器功能对您的代码进行了一些调整。我希望这有帮助。如果您在此问题上需要任何进一步的帮助,请告诉我。干杯!
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;
推荐阅读
- javascript - 选择文字时自动弹出菜单
- java - 如果在同步方法中调用等待方法,我的 java 单元测试失败
- python - Python re.findall 不匹配 HTML 中的 JS 变量
- python - Flask/Jinja 错误:jinja2.exceptions.TemplateSyntaxError:预期令牌“名称”,得到“字符串”
- react-native - react-native FlatList undefined 不是对象(评估'props.getItem')
- flutter - 尝试添加路径来定位颤振以运行“颤振医生”以解决“zsh:找不到命令:颤振”
- pivot-table - 在 Finicast 中,我无法将公式应用于数据透视表中的一组单元格
- php - Roundcube附件上传内部服务器错误
- amazon-web-services - 客户端到客户端的通信在 AWS Lightsail Debian Linux OpenVPN 服务器上不起作用
- pine-script - valuewhen() 没有提供正确的值