React中如何从动态加载的数据中获取所有多选框的选中值
Hey there! Let's fix your issue with getting the selected values from your dynamic checkboxes. The main problems in your current code are:
- The initial
isCheckedstate is initialized with an emptyusersarray, so it stays empty even after users load - You're only tracking boolean values by index, which isn't reliable if your user list ever changes order, and doesn't directly give you the selected user data
Here's a revised approach that solves both problems:
Step 1: Fix State Initialization & Sync
Instead of using an array for isChecked, use an object where keys are user IDs (unique identifiers) and values are booleans. This avoids index-related bugs and makes it easier to track selections. We'll also sync the state when the users data loads.
Step 2: Update Checkbox Change Handler
Modify the onChange handler to update the state using the user's ID instead of index.
Step 3: Retrieve Selected Users
Add a way to filter the users array based on the isChecked state to get the selected items.
Revised Code
import * as React from "react"; import Checkbox from "@mui/material/Checkbox"; import FormControlLabel from "@mui/material/FormControlLabel"; import axios from "axios"; export default function Checkboxes() { const [users, setUsers] = React.useState([]); // Use an object to track checked state by user ID const [isChecked, setIsChecked] = React.useState({}); React.useEffect(() => { getUsers(); }, []); // Sync checked state when users load: set all to false initially React.useEffect(() => { if (users.length > 0) { const initialCheckedState = users.reduce((acc, user) => { acc[user.id] = false; return acc; }, {}); setIsChecked(initialCheckedState); } }, [users]); const getUsers = async () => { try { const response = await axios.get( "https://jsonplaceholder.typicode.com/users" ); setUsers(response.data); } catch (error) { console.error(error); } }; const handleCheckboxChange = (userId) => { setIsChecked(prevState => ({ ...prevState, [userId]: !prevState[userId] })); }; // Get all selected users const selectedUsers = users.filter(user => isChecked[user.id]); console.log("Selected Users:", selectedUsers); return ( <div> {users.map((user) => { return ( <FormControlLabel key={user.id} control={ <Checkbox checked={isChecked[user.id] || false} onChange={() => handleCheckboxChange(user.id)} /> } label={user.name} /> ); })} <h3>Selected Users:</h3> <pre>{JSON.stringify(selectedUsers, null, 4)}</pre> </div> ); }
Key Improvements:
- ID-based tracking: Using user IDs instead of indexes ensures your checked state stays accurate even if the user list order changes
- Automatic state sync: The second useEffect initializes the checked state as soon as users are loaded
- Easy access to selected data: The
selectedUsersvariable gives you the full objects of all checked users, which you can use for further processing (like submitting a form)
If you need just the IDs or names of selected users instead of full objects, you can modify the filter:
// Get selected user IDs const selectedUserIds = users.filter(user => isChecked[user.id]).map(user => user.id); // Get selected user names const selectedUserNames = users.filter(user => isChecked[user.id]).map(user => user.name);
内容的提问来源于stack exchange,提问作者razer

