Reputation: 1208
I have a component where after clicking a button, the function updates the state (order) which rerenders the componet but updates only the span's text. Shouldn't the 'i tag' be rerendered as well?
const {useState, useEffect} = React;
const SortType = {
UNSORTERED: { icon: 'fas fa-sort', next: 'ASCENDING' },
ASCENDING: { icon: 'fas fa-sort-up', next: 'DESCENDING' },
DESCENDING: { icon: 'fas fa-sort-down', next: 'UNSORTERED' }
}
const Sorter = ({ trigger, sortOrder }) => {
const [order, setOrder] = useState(SortType.UNSORTERED)
function onSort() {
const nSortOrder = SortType[order.next]
setOrder(nSortOrder)
trigger(nSortOrder)
}
useEffect(() => {
if (sortOrder) {
setOrder(sortOrder)
}
}, [sortOrder])
return (
<button onClick={onSort}>
<i className={order.icon}/>
<span>{order.icon}</span>
</button>
)
}
ReactDOM.render(
<Sorter trigger={console.log} sortOrder={SortType.UNSORTERED} />,
document.getElementById("react")
);
<script src="https://use.fontawesome.com/releases/v5.11.2/js/all.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Actual result vs Expected result
Upvotes: 2
Views: 79
Reputation: 9958
I think the problem is with your font-awesome's cdn link. Because as we've all seen, the value of order.icon
did change, the className of the i tag did change, but then it rendered the weird svg component with an unchanged class of "fa-sort". Just replaced with another cdn link of fontawesome here, and it worked properly.
const {useState, useEffect} = React;
const SortType = {
UNSORTERED: { icon: 'fas fa-sort', next: 'ASCENDING' },
ASCENDING: { icon: 'fas fa-sort-up', next: 'DESCENDING' },
DESCENDING: { icon: 'fas fa-sort-down', next: 'UNSORTERED' }
}
const Sorter = ({ trigger, sortOrder }) => {
const [order, setOrder] = useState(SortType.UNSORTERED)
function onSort() {
const nSortOrder = SortType[order.next]
setOrder(nSortOrder)
trigger(nSortOrder)
}
useEffect(() => {
if (sortOrder) {
setOrder(sortOrder)
}
}, [sortOrder])
return (
<button onClick={onSort}>
<i className={order.icon}></i>
<span>{order.icon}</span>
</button>
)
}
ReactDOM.render(
<Sorter trigger={console.log} sortOrder={SortType.UNSORTERED} />,
document.getElementById("react")
);
<!-- REPLACED HERE -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Upvotes: 1