问题
Instructions
Create a web interface that allows a user:
To filter a list of players based on specific criteria. These are the search filters you will be creating based on the test data:
Age: allow the user to filter for players within a specific age or age range (e.g. 7, 5-9, 15-17, etc.)
Gender: allow the user to filter for players based on their specified gender
State: allow the user to filter for players based on the state they reside in from available test data
Status: allow the user to filter for players based on their status (active/inactive)
You can apply more than one filter to narrow down your search results.
To edit the information of any player.
CODE
I'm trying to use React Hooks, just wanting a few points of clarity on what I'm doing.
1) I'm wondering if my initial state for each variable makes sense. Also, on the useEffect method, that just needs to be run once to fetch the data with axios and that's all that is needed correct?
2) Just need 4 separate functions that handle each criteria. Would I just need to map
through the array of objects and filter
the wanted results?
import React, { useEffect, useState } from 'react';
import axios from 'axios';
const App = () => {
const url = "https://dii-test.s3.amazonaws.com/players.json";
const [age, setAge] = useState([]);
const [gender, setGender] = useState([]);
const [state, setState] = useState('');
const [status, setStatus] = useState(false);
useEffect(() => {
axios.get(url).then(json => setAge(json.data))
}, []);
const renderTable = () => {
return age.map(user => {
return (
<tr>
<td>{user.age}</td>
</tr>
)
})
}
return (
<div className="App">
<tbody>{renderTable()}</tbody>
</div>
);
}
export default App;
回答1:
I'd have a single state object for the players and then another (or multiple) to keep track of the filters. Something like:
const [genderFilter, setGenderFilter] = useState(null)
const [players, setPlayers] = useState([])
Then you can filter them in one fell swoop - either a series of tests inside a filter
of the players array, or in a series of filters
if you find chaining more readable and performant:
return (
<table>
<tbody>
{players.map(player => {
// After all the filters are run, map the players to table rows
return (
<tr>
<td>{player.name}</td>
<td>{player.age}</td>
<td>{player.state}</td>
<td>{player.gender}</td>
<td>{player.status}</td>
</tr>
)
}).filter(player => {
// genderFilter can be "male", "female", or null
return genderFilter ? player.gender === genderFilter : true
}).filter(player => {
// ageFilter is an object with min & max
return player.age >= ageFilter.min && player.age <= ageFilter.max
}).filter(player => {
// stateFilter can be a string or null
return stateFilter ? player.state == stateFilter : true
}).filter(player => {
// statusFilter can be "active" or "inactive"
return statusFilter === player.status
})}
</tbody>
</table>
)
That's the quick, dirty, and ugly version just to show the logic. It obviously doesn't include any displays/messages if the filters end up removing all players, waiting/loading message for the user during the axios call, etc.
And this is also only for a small to medium sized data set - if you have to download and filter thousands of results on the client side, it will be slow and your user would be better served sending the data to the server to query and return just the appropriate results.
来源:https://stackoverflow.com/questions/57262633/filtering-json-results-in-categories-react-hooks