I'm really new on React, Redux. I am trying to display the selected value from dropdown, uses semantic ui. I updated at state but can not show the value on the screen, and the dropdown not close (after added closeOnChange- not recognize this attribute, why?}
** Component.js**
const ProductDetails = () => {
const {productId} = useParams()
const selectedProd = useSelector((state) => state.allProducts.products.find(product =>
product.id === parseInt(productId)
));
const products = useSelector((state) => state.allProducts.products)
let {rank} = selectedProd
const dispatch = useDispatch()
const handleDropDownSelect = (event) => {
//update rank
selectedProd.rank = parseInt(event.dataset.value)
//update allProducts
dispatch(updateProducts(products,selectedProd))
}
return(
<div className="ui left floated simple selection dropdown" value={rank} onClick={e=>handleDropDownSelect(e.target)}>
<i className="dropdown icon"></i>
<div className="default value" value={rank}></div>
<div className="left floated menu" >
<div className="item" data-value="1" data-key="1">1</div>
<div className="item" data-value="2" data-key="2">2</div>
<div className="item" data-value="3" data-key="3">3</div>
<div className="item" data-value="4" data-key="4">4</div>
<div className="item" data-value="5" data-key="5">5</div>
</div>
</div>)
redux/reducers/actions.js
export const updateProducts = (products,product) => {
const indexOfItem = products.findIndex(q => q.id === product.id);
if (indexOfItem > -1) {
products[indexOfItem] = product;
}
return {
type: ActionTypes.SET_PRODUCTS,
payload: products
};
};
redux/constans/types.js
export const ActionTypes = {
SET_PRODUCTS: "SET_PRODUCTS",
}
redux/reducers/index.js
import { combineReducers } from 'redux'
import { productReducer} from './productReducer'
const reducers = combineReducers({
allProducts: productReducer,
})
export default reducers
What I'm missing?
This is most likely you do NOT change the reference of state.allProducts.products
, so React doesn't re-render the UI
You should map
products as the Redux Todos Example
And add a online demo such as CodeSandBox would help us give you better suggestions
OK, according to the demo at codesandbox.io/s/products-forked-kmbwz, here we have at leaset two problems:
ProductDetails
didn't rerender after the dropdown select chance because of you didn't change the reference of selectedProd
.View on this link I forked from yours, see file /src/Components/ProductDetails.js
on Line 14-15, I add a console.log to debug the Component whether will be rerendered. And Line 31-33, I change the reference of new selectedProd
by destructuring assignment. The when you click the dropdown option, the UI will be rerender, because you see the log.
div
. But div
doesn't have a value
prop, you should explicitly display it as I do at Line 54.handleDropDownSelect
event, so you will see NaN sometimesI really suggest you follow the official Redux Todos Example before you start. And the problem you face here is that, React naturally render the UI when data(props/state) change, so the reference of data is change or not is important to React. And as you play React longer, immutable data structure such as Immerjs will help a lot. And again, the Redux or React docs are much more detailed than I explained, read them🤪