1

enter image description here Here the singleCard object has all the details about the product such as id, title, src etc. I can console log the singleCard as console.log(singleCard) which shows all the data passed from redux store , but I can't get access to its individual elements like singleCard.src or singleCard.title . I want to showcase the images by the help of the useState hook by setting the initialState to singleCard.src , how can I do that??

    

        function Singlecard() {
        
        
          const dispatch = useDispatch();
          const { id } = useParams();
          const productId = id;
          const productDetails = useSelector((state) => state.productDetails);
          const { loading, error, singleCard } = productDetails;
        
          const [currentImg, setcurrentimg] = useState(singleCard.src);
        
          console.log(currentImg);
        
          useEffect(() => {
            dispatch(detailsProduct(productId));
          }, [dispatch, productId]);
    
         return (
            <div>
               <div className="singlecard-wrapper">
                  <div className="singlecard">
                    {/* card left */}
                    <div className="product-img">
                      <div className="img-display">
                        <div className="img-showcase">
                          <img src={currentImg} height="552px" width="552px" />
                        </div>
                      </div>
                      <div className="img-select">
                        <div className="img-item">
                          <Link to="#">
                            <img
                              src="https://instagram.fccu3-1.fna.fbcdn.net/v/t51.2885-15/e35/121105212_197680348436281_873870113726337107_n.jpg?tp=1&_nc_ht=instagram.fccu3-1.fna.fbcdn.net&_nc_cat=101&_nc_ohc=nsNxf_rVgeUAX9KUkp-&edm=AP_V10EAAAAA&ccb=7-4&oh=6b955579988a6dcbef129b3ad606fecd&oe=60918B32&_nc_sid=4f375e"
                              onClick={(e) => setcurrentimg(e.target.src)}
                            />
                          </Link>
                        </div>
                   </div>
              </div>
        </div>
     </div>

on using singleCard.src in useState it shows cannot read property 'src' of undefined . Please help !

productAction:


    export const detailsProduct = (productId) => async (dispatch) => {
  dispatch({ type: PRODUCT_DETAILS_REQUEST, payload: productId });
  try {
    const response = await axios.get(`/cardUpload/${productId}`);
    dispatch({ type: PRODUCT_DETAILS_SUCCESS, payload: response.data });
  } catch (err) {
    dispatch({
      type: PRODUCT_DETAILS_FAIL,
      payload:
        err.response && err.response.data.message
          ? err.response.data.message
          : err.message,
    });
  }
};

productReducer:


    export const detailsProduct = (productId) => async (dispatch) => {
  dispatch({ type: PRODUCT_DETAILS_REQUEST, payload: productId });
  try {
    const response = await axios.get(`/cardUpload/${productId}`);
    dispatch({ type: PRODUCT_DETAILS_SUCCESS, payload: response.data });
  } catch (err) {
    dispatch({
      type: PRODUCT_DETAILS_FAIL,
      payload:
        err.response && err.response.data.message
          ? err.response.data.message
          : err.message,
    });
  }
};

store:


import { applyMiddleware, combineReducers, compose, createStore } from "redux";
import thunk from "redux-thunk";
import {
  productDetailsReducer,
  productListReducer,
} from "./reducers/productReducers";
const initialState = {};

const reducer = combineReducers({
  productList: productListReducer,
  productDetails: productDetailsReducer,
});

const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,
  initialState,
  composeEnhancer(applyMiddleware(thunk))
);

export default store;

Souradeep
  • 11
  • 2
  • But why are you trying to use useState with a value that came from useSelector? why not use the value directly? – Jonathan Alfaro May 12 '21 at 18:24
  • In my experience is not a good idea to "combine" different "sources" of "state". – Jonathan Alfaro May 12 '21 at 18:25
  • If i use the value directly then on clicking the div named "img-item" the src won't change dynamically as the useState requires a valid initial state . – Souradeep May 12 '21 at 19:00
  • once agin you are "combining" different states.... if you get a state from the Store then you need to use a reducer to change it. So if you get productDetails from the store then when you click on img-item you should change the value in the store by using a reducer. In other words it not a good idea to get some value from the store and expect to use it as local state "useState". The right pattern in my opinion is that if the state is local you handle local if the state is from the store you handle it with a reducer – Jonathan Alfaro May 13 '21 at 00:46
  • useState, useSelector dont mix very well. choose one place and one place only to store a value. So if you want to store the currentImg in the store then get it using useSelector and change it using a reducer call. If you want to store the currentImg in localState then get it using useState and set it with the same function. But do not combine these two different ways of handling state or you will be deep in a rabbit hole – Jonathan Alfaro May 13 '21 at 00:49
  • Thanks For explaining in detail , I will try a different approach now where I will not mix different states. Thank you – Souradeep May 13 '21 at 05:19

0 Answers0