So I am trying to learn React, and have a quite simple application I am trying to build.
So I have a backend API returning a list of say 1000 items, each item has a name and a code. I want to put out all the names of this list into check boxes. And then do X with all selected items - say print the name, with a selectable font to a pdf document.
With this I also want some easy features like "select all" and "deselect all".
So since I am trying to learn react I am investigating a few different options how to do this. None seems good.
So I tried making a child ponent for each checkbox, felt clean and "react". This seems to be really bad performance, like take 2-3 seconds for each onChange callback so I skipped that.
I tried making a Set in the class with excluded ones. This too seems to be really slow, and a bad solution since things like "select all" and "deselect all" will be really ugly to implement. Like looping through the original list and adding all of them to the excluded set.
Another solution I didn't get working is modifying the original data array. Like making the data model include a checked boolean to get a default value, and then modify that. But then the data needs to be a map instead of an array. But I have a feeling this solution will be really slow too whenever clicking the checkbox. I dont quite understand why it is so slow to just do a simple checkbox.
So please tell me how to approach this problem in react.
A few direction questions:
How do I modify an array when I fetch it, say add a checked: true variable to each item in the array?
async ponentDidMount() {
const url = "randombackendapi";
const response = await fetch(url);
const data = await response.json();
this.setState({ data: data.data, loading: false });
}
Why is this so extremely slow? (Like take 3 seconds each click and give me a [Violation] 'click' handler took 3547ms) warning. And my version of each item being a sub function with callback being equally slow. How can I make this faster? - Edit this is the only question that remains.
{this.state.data.map((item, key) => (
<FormControlLabel
key={item.code}
label={item.name}
control={
<Checkbox
onChange={this.handleChange.bind(this, item.code)}
checked={!this.state.excludedSets.has(item.code)}
code={item.code}
/>
}
/>
))}
handleChange = (code, event) => {
this.setState({
excludedSets: event.target.checked
? this.state.excludedSets.delete(code)
: this.state.excludedSets.add(code)
});
};
I guess I don't understand how to design my react ponents in a good way.
So I am trying to learn React, and have a quite simple application I am trying to build.
So I have a backend API returning a list of say 1000 items, each item has a name and a code. I want to put out all the names of this list into check boxes. And then do X with all selected items - say print the name, with a selectable font to a pdf document.
With this I also want some easy features like "select all" and "deselect all".
So since I am trying to learn react I am investigating a few different options how to do this. None seems good.
So I tried making a child ponent for each checkbox, felt clean and "react". This seems to be really bad performance, like take 2-3 seconds for each onChange callback so I skipped that.
I tried making a Set in the class with excluded ones. This too seems to be really slow, and a bad solution since things like "select all" and "deselect all" will be really ugly to implement. Like looping through the original list and adding all of them to the excluded set.
Another solution I didn't get working is modifying the original data array. Like making the data model include a checked boolean to get a default value, and then modify that. But then the data needs to be a map instead of an array. But I have a feeling this solution will be really slow too whenever clicking the checkbox. I dont quite understand why it is so slow to just do a simple checkbox.
So please tell me how to approach this problem in react.
A few direction questions:
How do I modify an array when I fetch it, say add a checked: true variable to each item in the array?
async ponentDidMount() {
const url = "randombackendapi";
const response = await fetch(url);
const data = await response.json();
this.setState({ data: data.data, loading: false });
}
Why is this so extremely slow? (Like take 3 seconds each click and give me a [Violation] 'click' handler took 3547ms) warning. And my version of each item being a sub function with callback being equally slow. How can I make this faster? - Edit this is the only question that remains.
{this.state.data.map((item, key) => (
<FormControlLabel
key={item.code}
label={item.name}
control={
<Checkbox
onChange={this.handleChange.bind(this, item.code)}
checked={!this.state.excludedSets.has(item.code)}
code={item.code}
/>
}
/>
))}
handleChange = (code, event) => {
this.setState({
excludedSets: event.target.checked
? this.state.excludedSets.delete(code)
: this.state.excludedSets.add(code)
});
};
I guess I don't understand how to design my react ponents in a good way.
Share Improve this question edited Apr 15, 2020 at 7:01 nesohc asked Apr 11, 2020 at 22:06 nesohcnesohc 4971 gold badge6 silver badges14 bronze badges 2-
What is the
this.state.excludedSets
? – Pablo Commented Apr 12, 2020 at 0:17 - excludedSets: new Set() – nesohc Commented Apr 12, 2020 at 17:20
3 Answers
Reset to default 3How do I modify an array when I fetch it, say add a checked: true variable to each item in the array?
Once you have the array you can use a map
to add a checked key, which will just make the process much easier by utilizing map
on the main array to check and an easier implementation for the select-deselect all feature
let data = [{code: 1},{code: 2},{code: 3}]
let modifiedData = data.map(item => {
return {...item, checked: false}
})
//modifiedData = [ { code: 1, checked: false }, { code: 2, checked: false }, { code: 3, checked: false } ]
I would remend to save the modified data inside the state instead of the data you fetched since you can always modify that array to send it back to the api in the desired format
now that you have the modified array with the new checked
key you can use map
to select and deselect like so
const handleChange = (code) => {
modifiedData = modifiedData.map(item => item.code === code ? {...item, checked: !item.checked}: item)
}
And as of the deselect all | select all you can use another map
method to do this like so
const selectAllHandler = () => {
modifiedData = modifiedData.map(item => {
return {...item, checked: true}})
}
and vice-versa
const deselectAllHandler = () => {
modifiedData = modifiedData.map(item => {
return {...item, checked: false}})
}
It's a mon rendering issue React will have, you can use virtualize
technique to reduce the amount of DOM elements to boost the re-rendering time.
There're several packages you can choose, like react-virtuoso
, react-window
etc.
The main concept is to only render the elements inside your viewport and display others when you're scrolling.
So I was unable to get the React checkbox ponent performant (each click taking 2-3 seconds), so I decided to just go with html checkboxes and pure javascript selectors for my needs, works great.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745103057a4611390.html
评论列表(0条)