React-Redux, How to set global state before new component is rendered?

Viewed 134

I am currently learning react-redux and I am attempting to update the global state with an array that is fetched from an API. When the onClick event is fired the page renders the new component before the global state can be set. When NavLink is set to '#' the state is able to be set. How could I have redux populate the state before rendering the new component?

My main objective is to pass the fetched array to a different component to display the fetched information.

COMPONENT

function Selector(props) {
  const [alcoholCategory, setAlcoholCategory] = useState([]);

useEffect(() => {
    props.handleCategorySelection(alcoholCategory);
  });

  function handleImagePress(alc) {
    fetch(`https://www.thecocktaildb.com/api/json/v1/1/filter.php?i=${alc}
    `)
      .then((r) => r.json())
      .then((result) => setAlcoholCategory(result.drinks))
      .then(props.handleCategorySelection(alcoholCategory));
  }
  console.log(alcoholCategory);
  return (
    <div className="selector-div">
      <ul>
        <li>
          <NavLink to="vodka" onClick={() => handleImagePress("Vodka")}>
            <img
              src="https://hips.hearstapps.com/vader-prod.s3.amazonaws.com/1583334281-smirnoff-1583334273.png"
              alt="alcohol-bottle"
              className="selector-bottle-img"
            ></img>
          </NavLink>
          <label>Vodka</label>
        </li>
<li>
          <a href="/rum" onClick={() => handleImagePress("Rum")}>
            <img
              src="https://hips.hearstapps.com/vader-prod.s3.amazonaws.com/1583334281-smirnoff-1583334273.png"
              alt="alcohol-bottle"
              className="selector-bottle-img"
            ></img>
          </a>
          <label>Rum</label>
        </li>
        <li>
          <a href="/tequila" onClick={() => handleImagePress("Tequila")}>
            <img
              src="https://hips.hearstapps.com/vader-prod.s3.amazonaws.com/1583334281-smirnoff-1583334273.png"
              alt="alcohol-bottle"
              className="selector-bottle-img"
            ></img>
          </a>
          <label>Tequila</label>
        </li>
      </ul>
    </div>
  );
}

const mapDispatchToProps = (dispatch) => {
  return {
    handleCategorySelection: (drinks) =>
      dispatch({ type: "DRINK_LIST", drinkArray: drinks }),
  };
};
export default connect(null, mapDispatchToProps)(Selector);

REDUCER

const initialState = { drinkList: [] };

const alcoholCategory = (state = initialState, action) => {
  switch (action.type) {
    case "DRINK_LIST":
      return {
        ...state,
        drinkList: state.drinkList.concat(action.drinkArray),
      };
  }
};

export default alcoholCategory;
1 Answers

You could conditionally render the new component around the store property it is dependent on.

Parent Component:

import React from 'react';
import {connect} from 'redux';
import anyActionYouNeed from '../actions/anyActionYouNeed'

const mapStateToProps = state => {
  return {
    drinkList: state.drinkList,
  }
}

const mapDispatchToProps = {
  anyActionYouNeed
}

//drinkList.length > 0 in your case
let Parent = ({drinkList, anyActionYouNeed}) => {
  return(
    <div>
      {drinkList.length > 0 && <NewComponent drinkList={drinkList}/>}
    </div>
  )
}

Parent = connect(
  mapStateToProps,
  mapDispatchToProps
)(Parent)

export default Parent
Related