I was following a tutorial on sorting an table.
Now at last part I've noticed that in the tutorial, person was using useMemo
where I don't use it at all. Now problem is that I cannot change my code because of this feature, so I'm asking you guys is something that I do to get sorting working??
I think my first problem is that I'm using one object who has key:value pairs and where values are arrays, and in tutorial response is arrays of objects. When I try to sort my arrays I get error dataArr[0].map is not a function
and this function works in the render. Also I get console.log
of undefined when trying to console.log(arr)
inside of useMemo
but if i use it outside, i get normal log of data.
Also I'm recently started learning ReactJS and I never came across useMemo
.
Link to github of the tutorial
My component where I implemented this:
import React, { useEffect, useState, useRef, useMemo } from 'react';
import { Link } from 'react-router-dom';
import Form from 'react-validation/build/form';
import Input from 'react-validation/build/input';
import CheckButton from 'react-validation/build/button';
import TableHeader from './TableHeader';
import ArticleService from '../services/article.service';
const Article = (props) => {
const form = useRef();
const checkBtn = useRef();
const [value, setValue] = useState('');
const [content, setContent] = useState([]);
const [dataArr, setDataArr] = useState([]);
const [sorting, setSorting] = useState({ field: '', order: '' });
const headers = [
{ name: 'Informacije o banci', field: 'bankname', sortable: false },
{ name: 'NKS', field: 'nks', sortable: true },
{ name: 'Ukupna cijena', field: 'price', sortable: true },
{ name: 'Mjese?na rata', field: 'rate', sortable: true },
];
const [months, setMonths] = useState([]);
const [loading, setLoading] = useState(false);
const onChangeMonths = (e) => {
const months = e.target.value;
setMonths(months);
};
const handleMonths = async (e) => {
e.preventDefault();
setLoading(true);
if (checkBtn.current.context._errors.length === 0) {
const id = props.match.params.id;
try {
const res = await ArticleService.article(id, months);
setContent(res.data);
const data = res.data.kredit;
const dataArr = [];
dataArr.push({
name: 'kreditNKS-rataNKS',
price: data.kreditNKS.map((item) => {
return item;
}),
rate: data.rataNKS.map((item) => {
return item;
}),
nks: data.stopaNKS.map((item) => {
return item;
}),
eks: data.stopaEKS.map((item) => {
return item;
}),
bankname: data.ime.map((item) => {
return item;
}),
type: data.tip.map((item) => {
return item;
}),
});
setDataArr(dataArr);
setLoading(false);
} catch (e) {
setLoading(false);
}
} else {
setLoading(false);
}
};
useEffect(() => {
const fetchPosts = async () => {
const id = props.match.params.id;
const res = await ArticleService.article(id);
setContent(res.data);
const data = res.data.kredit;
const dataArr = [];
dataArr.push({
name: 'kreditNKS-rataNKS',
price: data.kreditNKS.map((item) => {
return item;
}),
rate: data.rataNKS.map((item) => {
return item;
}),
nks: data.stopaNKS.map((item) => {
return item;
}),
eks: data.stopaEKS.map((item) => {
return item;
}),
bankname: data.ime.map((item) => {
return item;
}),
type: data.tip.map((item) => {
return item;
}),
});
setDataArr(dataArr);
};
fetchPosts();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const data = useMemo(() => {
const arr = dataArr;
console.log(arr);
if (sorting.field) { <--------- This part i need to implement somewhere in the code
const reversed = sorting.order === 'asc' ? 1 : -1;
return (
dataArr[0] &&
dataArr[0].map((item) =>
item.nks.sort(
(a, b) =>
reversed * a[sorting.field].localeCompare(b[sorting.field])
)
)
);
}
}, [sorting]);
return (
<div>
<p className='text-dark'>
<Link to='/dashboard'>
<i className='fas fa-arrow-left'></i> Nazad
</Link>
</p>
<div className='container p-3 my-3 bg-dark text-white'>
<strong>Artikal id:{content.id}</strong>
<br></br>
<br></br>
<div className='row'>
<div className='col-sm'>
Opis:
<br></br>
{content.descr}
</div>
<div className='col-sm'>
Cijena
<br></br>
{content.price}
</div>
<div className='col-sm'>
Cijena po metru kvadratnom:
<br></br>
{content.ppm2}/m2
</div>
</div>
</div>
<div className='container'>
<h3>KREDITI ZA CIJENU {content.price}</h3>
<Form onSubmit={handleMonths} ref={form}>
<div className='form-group'>
<label>Vrijeme otplate u mjesecima:</label>
<Input
type='text'
className='form-control w-25'
name='months'
value={months}
onChange={onChangeMonths}
/>
<button
className='btn btn-primary btn-block w-25'
disabled={loading}
>
{loading && (
<span className='spinner-border spinner-border-sm'></span>
)}
<span>Prika?i</span>
</button>
<CheckButton style={{ display: 'none' }} ref={checkBtn} />
<small>
Ako se ne unese vrijeme otplate kredita, kredit se izra?unava za
60 mjeseci
</small>
<br></br>
<Input
type='text'
placeholder='Unos max. kamatne stope'
value={value}
onChange={(e) => setValue(e.target.value)}
/>
</div>
</Form>
</div>
<table className='table text-center'>
<TableHeader
headers={headers}
onSorting={(field, order) => setSorting({ field, order })}
/>
<tbody>
{dataArr[0] &&
dataArr[0].nks
.filter((item) => {
if (!value) {
return item;
} else {
return item < value;
}
})
.map((item, i) => (
<tr key={i}>
<td className='d-flex flex-column align-items-center'>
<h4>{dataArr[0].bankname[i]}</h4>
<span>EKS: {dataArr[0].eks[i]}</span>
<span>Tip: {dataArr[0].type[i]}</span>
</td>
<td className='align-middle'>
<h4>{item}</h4>
</td>
<td className='align-middle'>
<h4>{dataArr[0].price[i]} KM</h4>
</td>
<td className='align-middle'>
<h4>{dataArr[0].rate[i]} KM/mj</h4>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Article;
Note that clicking on header in the table, onClick
is triggered I just get an error and to be honest, I have no idea how to fix this.
Also if u have some tutorial of sorting that would be easy to implement into my project I would appreciate it. Thanks!
Here is console.log(dataArr[0])
and console.log(arr)
note that arr
one is undefiend.
question from:
https://stackoverflow.com/questions/65938685/is-there-a-way-to-implement-function-from-usememo-into-useeffect