I have a react native component that has flatlist of 20 items (Data). The item contains component which uses setTimeout. Would this cause any performance
handleSpinner = result => {
setTimeout(() => {
// handle task
}, 3000);
return<some stuff></some>
};
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
//...MORE ITEMS
];
<FlatList
keyExtractor={this.keyExtractor}
data={list}
renderItem={this.handleSpinner}
It will cause the serious problem when there are lots of data in the list.
Related
I'm building an application based on user survey in React JS.
All the questions are coming from API as JSON response
const data = {
preQuestions: {
landingPage: {
heading: 'This is the ladning page',
buttons: {
yesButton: {
text: 'yes',
action: '1A',
},
noButton: {
text: 'No',
action: '1B',
},
},
},
'1A': {
heading: 'This is the 1A Component',
buttons: {
yesButton: {
text: 'yes',
action: '1C',
},
noButton: {
text: 'No',
action: '1D',
},
},
},
'1B': {
heading: 'This is the 1B Component',
buttons: {
yesButton: {
text: 'yes',
action: '1C',
},
noButton: {
text: 'No',
action: '1D',
},
},
},
'1C': {
heading: 'This is the 1C Component',
buttons: {
yesButton: {
text: 'yes',
action: '1A',
},
noButton: {
text: 'No',
action: '1B',
},
},
},
'1D': {
heading: 'This is the 1D Component',
buttons: {
yesButton: {
text: 'yes',
action: '1B',
},
noButton: {
text: 'No',
action: '1C',
},
},
},
},
};
I wanted to display only 1st question by default and based on the user response I need to load the second question on same page, where use can able to see the previous question .
Basically I wanted to stack all the questions one below the other based on user actions.
But current with my logic, When user selects the next question, prev question getting disappeared.
Below is my code,
const [active, setActive] = React.useState<any>(
data.preQuestions['landingPage']
);
const content = data.preQuestions;
const loadNextCompnent = (actionId) => {
setActive(actionId);
};
const renderQustionComponent = () => {
Previous question
return (
<div>
<h1>{active?.heading}</h1>
<button
onClick={() =>
loadNextCompnent(content[active?.buttons?.yesButton?.action])
}
>
{active.buttons.yesButton.text}{' '}
</button>
<button
onClick={() =>
loadNextCompnent(content[active?.buttons?.noButton?.action])
}
>
{active.buttons.noButton.text}{' '}
</button>
</div>
);
};
return <div>{renderQustionComponent()}</div>;
How Can I stack all the questions one below the other ? Please help.
Working Stackblitz link https://stackblitz.com/edit/react-ts-z8clfj
I'm sure if you're using ant design menu component you've got the same error:
Warning: [antd: Menu] children will be removed in next major version. Please use items instead.
the new way to make this is:
const items = [
{ label: 'item 1', key: 'item-1' },
{ label: 'item 2', key: 'item-2' },
{
label: 'sub menu',
key: 'submenu',
children: [{ label: 'item 3', key: 'submenu-item-1' }],
},
];
return <Menu items={items} />
and you can define your function and use it like this:
return <Menu onClick={onClick} selectedKeys={[current]} mode="horizontal" items={items} />;
how can i have different functions on my items?
i'll be glad if someone help me with this
in the old way i could easily define any functions i want on any items
Actually, we can add functions to the items array as well
const [current, setCurrent] = useState();
const func = () => {
setCurrent(e.key);
}
const func2 = () => {
setCurrent(e.key);
}
const items = [
{
label: 'item 1',
key: 'item-1'
onClick: func,
className: class1,
},
{
label: 'item 1',
key: 'item-1'
onClick: func2,
className: class2,
},,
{
label: 'sub menu',
key: 'submenu',
children: [{ label: 'item 3', key: 'submenu-item-1' }],
},
];
return <Menu selectedKeys={[current]} mode="horizontal" items={items} />;
So I am using the Antd Cascader component (for the first time, having used Antd Select for most other things for the past few months). However, it isn't quite working yet. I have the options basically like this (but with a lot more options, only 3 levels deep tho like this):
const options = [
{
label: 'Base 1',
value: 'base_1',
children: [
{
label: 'Middle a',
value: 'middle_a',
children: [
{
label: 'Foo',
value: 'd57b2b75-4afa-4a16-8991-fc736bce8cd5',
},
{
label: 'Bar',
value: 'd12b2b75-4afa-4a16-8991-fc736bce8cec',
}
]
},
{
label: 'Middle b',
value: 'middle_b',
children: [
{
label: 'Baz',
value: 'd32b2b75-4afa-4a16-8991-fc736bce8cdd',
},
{
label: 'Quux',
value: 'dabb2b75-4afa-4a16-8991-fc736bce8ced',
}
]
}
]
},
{
label: 'Base 2',
value: 'base_2',
children: [
{
label: 'Middle a',
value: 'middle_a',
children: [
{
label: 'Helo',
value: 'd32bce75-4afa-4a16-8991-fc736bce8cdd',
},
{
label: 'World',
value: 'dabbac75-4afa-4a16-8991-fc736bce8ced',
}
]
}
]
}
]
I configure the component like this:
<Cascader
options={options}
getPopupContainer={trigger => trigger.parentNode}
multiple={multiple}
displayRender={label => {
return label.join(' / ');
}}
value={defaultValue}
// eslint-disable-next-line #typescript-eslint/no-explicit-any
onChange={(val: any, options: any) => {
if (multiple) {
const ids = serializeCascaderOptionValues(options);
onChange?.(ids, options);
} else {
onChange?.(val[2] ? String(val[2]) : undefined, options);
}
}}
showSearch={{
filter: (input: string, path) => {
return path.some(
option =>
String(option?.label).toLowerCase().indexOf(input.toLowerCase()) >
-1
);
},
}}
/>
Where, here, value or defaultValue I am passing in an array like ['d32bce75-4afa-4a16-8991-fc736bce8cdd'], which maps to Base 2 / Middle a / Helo. When I select the value Base 2 / Middle a / Helo from the UI, it shows correctly in the input like that. But when I save it and refresh the page (persisting to the backend, and pass in value={value} like value={['d32bce75-4afa-4a16-8991-fc736bce8cdd']}, it shows the ID hash in the input instead of the nice string Base 2 / Middle a / Helo. When I log displayRender={label...}, the label is showing the [ID-hash], rather than an array of like ['Base 2', 'Middle a', 'Helo']. What am I doing wrong, how do I get it to show properly?
I'm currently learning ReactJs and using Ant Design as a UI library. I have some problems when I tried to use the Selection (Checkbox Table). At first, it's fine with some basic interaction, I can get the selectedRowKeys, the selectedRow data normally to interact with the database. But when I need the Table to check some rows according to the data, it got some problems. When I set the props selectedRowKeys with data, it selects the right checkbox I want but I can't uncheck or select another checkbox. It shows the error:
Uncaught TypeError: clone.push is not a function at arrAdd ...
Here's how I'm doing it:
import React, { useState } from 'react';
import { Table, Radio, Divider } from 'antd';
const columns = [
{
title: 'Name',
dataIndex: 'name',
render: (text) => <a>{text}</a>,
},
{
title: 'Age',
dataIndex: 'age',
},
{
title: 'Address',
dataIndex: 'address',
},
];
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Jack',
age: 20,
address: 'Somewhere else',
},
]; // rowSelection object indicates the need for row selection
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
},
getCheckboxProps: (record) => ({
name: record.name,
}),
};
const Demo = () => {
const dataKeys = "1,2"; //after handling data from server, I got a string like this which I can pass to Table
return (
<div>
<Table
rowSelection={{
selectedRowKeys: dataKeys,
type: selectionType,
...rowSelection,
}}
columns={columns}
dataSource={data}
/>
</div>
);
};
ReactDOM.render(<Demo />, mountNode);
Given is following data structure
const list = [
{
title: 'Section One',
data: [
{
title: 'Ay',
},
{
title: 'Bx',
},
{
title: 'By',
},
{
title: 'Cx',
},
],
},
{
title: 'Section Two',
data: [
{
title: 'Ay',
},
{
title: 'Bx',
},
{
title: 'By',
},
{
title: 'Cx',
},
],
},
];
What i want to do ist to filter this list based on title property in the data array of each object.
An example would be to have the list where the title property of the childs starts with "B", so the list will look like that:
const filteredList = [
{
title: 'Section One',
data: [
{
title: 'Bx',
},
{
title: 'By',
}
],
},
{
title: 'Section Two',
data: [
{
title: 'Bx',
},
{
title: 'By',
}
],
},
];
What i tried so far was something like that:
const items = list.filter(item =>
item.data.find(x => x.title.startsWith('A')),
);
or
const filtered = list.filter(childList => {
childList.data.filter(item => {
if (item.title.startsWith('B')) {
return item;
}
return childList;
});
});
But i think i am missing a major point here, maybe some of you could give me a tip or hint what i am doing wrong
Best regards
Your issue is that you're doing .filter() on list. This will either keep or remove your objects in list. However, in your case, you want to keep all objects in list and instead map them to a new object. To do this you can use .map(). This way you can map your objects in your list array to new objects which contain filtered data arrays. Here's an example of how you might do it:
const list=[{title:"Section One",data:[{title:"Ay"},{title:"Bx"},{title:"By"},{title:"Cx"}]},{title:"Section Two",data:[{title:"Ay"},{title:"Bx"},{title:"By"},{title:"Cx"}]}];
const filterByTitle = (search, arr) =>
arr.map(
({data, ...rest}) => ({
...rest,
data: data.filter(({title}) => title.startsWith(search))
})
);
console.log(filterByTitle('B', list));