I've got a react app. And I was making filter section where user puts max price of article.
Now everything works, only thing that is, page is rerendering on every single input in input box, even there is an button.
What would be the way to stop rerendering of a page? I want it to rerender only if button is pressed - so I only want to remove this rerendering when user inputs a price. Eg. User want to input price 200000
but page refreshes when he types 2,0,0 etc. I want to be able to input 200000
without refreshing only if button is pressed.
Thanks!
Here is my dashboard.js
const Dashboard = () => {
const form = useRef();
const checkBtn = useRef();
const pageSearchParam = new URLSearchParams(window.location.search);
const pageParam = Number(pageSearchParam.get('page')) || 1;
const maxPriceSearchParam = new URLSearchParams(window.location.search);
const maxPriceParam = Number(maxPriceSearchParam.get('maxprice'));
const parsedUrl = new URL(window.location.href);
const filterNameInURL = parsedUrl.searchParams.get('filter');
const [content, setContent] = useState([]);
const [maxPrice, setMaxPrice] = useState(maxPriceParam || []);
// eslint-disable-next-line
const [page, setPage] = useState(pageParam);
const [total, setTotal] = useState(0);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (filterNameInURL) {
const fetchFiltered = async () => {
const res = await ArticleService.filterByName(filterNameInURL, page);
const { count, rows } = await res.data;
setTotal(count);
setContent(rows);
};
fetchFiltered();
} else if (maxPrice) {
const fetchWithMaxPrice = async () => {
const res = await ArticleService.filterByMaxPrice(maxPrice, page);
const { count, rows } = await res.data;
setTotal(count);
setContent(rows);
};
fetchWithMaxPrice();
} else {
const fetchPosts = async () => {
const res = await ArticleService.articles(page);
const { count, rows } = await res.data;
setTotal(count);
setContent(rows);
};
fetchPosts();
}
}, [filterNameInURL, page, maxPrice]);
const onChangeMaxPrice = (e) => {
const maxprice = e.target.value;
setMaxPrice(maxprice);
};
const handleFilter = async (e) => {
e.preventDefault();
form.current.validateAll();
setLoading(true);
if (checkBtn.current.context._errors.length === 0) {
try {
onsubmit = () => {
maxPriceSearchParam.set('maxprice', maxPrice);
window.location.search = maxPriceSearchParam.toString();
};
} catch (error) {
console.log(error);
}
} else {
setLoading(false);
}
};
const render = (item, index) => {
return (
<tr key={index}>
<td className='text-center'>
<div key={item.id}>
<img
src={`${item.pictures}`}
alt='picture'
className='rounded'
></img>
</div>
</td>
<td className='text-center'>
<div key={item.id}>
<h4>{item.descr}</h4>
<br></br>
<h6 className='text-left'>No of sqm: {item.sqm}m2</h6>
<div className='text-left'>
<small className='text-left'>
{' '}
<a href={item.link} target='_blank' rel='noopener noreferrer'>
Show on page
</a>
</small>
</div>
</div>
</td>
<td className='text-center'>
<div key={item.id}>
<h4>{item.price}</h4>
<small className='text-left'>Price per m2: {item.ppm2}</small>
</div>
</td>
<td className='text-center'>
<div key={item.id}>
<Link to={`/article/${item.id}`}>
<h4>Show</h4>
</Link>
</div>
</td>
</tr>
);
};
const capitalize = (str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
};
const renderHeader = () => {
if (filterNameInURL) {
return (
<h4 className='text-center'>
Total {total} articles on
{capitalize(filterNameInURL)}
</h4>
);
} else {
return (
<h4 className='text-center'>
Total {total} articles in DB
</h4>
);
}
};
return (
<div>
<div className='container'>
{renderHeader()}
<Form onSubmit={handleFilter} ref={form}>
Filters <br></br> Max price:
<input
type='text'
className='form text-center'
placeholder='npr. 120000'
aria-describedby='basic-addon2'
value={maxPrice}
onChange={onChangeMaxPrice}
/>
<button className='btn btn-primary btn-block w-25' disabled={loading}>
{loading && (
<span className='spinner-border spinner-border-sm'></span>
)}
<span>Filter</span>
</button>
<CheckButton style={{ display: 'none' }} ref={checkBtn} />
</Form>
<div className='table-responsive'>
<table className='table'>
<thead className='thead-dark'>
<tr>
<th className='text-center' scope='col'>
Picture
</th>
<th className='text-center' scope='col'>
Description
</th>
<th className='text-center w-25' scope='col'>
Price
</th>
<th className='text-center' scope='col'>
Offer
</th>
</tr>
</thead>
<tbody>{content.map(render)}</tbody>
</table>
</div>
</div>
<div className='mb-5 text-center'>
<Pagination
totalPages={Math.ceil(total / 10)}
onPageChange={(e, d) => {
pageSearchParam.set('page', d.activePage);
window.location.search = pageSearchParam.toString();
}}
activePage={page}
/>
</div>
</div>
);
};
export default Dashboard;
question from:
https://stackoverflow.com/questions/66047883/react-update-state-only-when-button-is-clicked-rather-than-updating-whenever-som 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…