简体   繁体   中英

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

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;

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM