skip to Main Content

I have a function that merges 2 objects. But I want this function to be executed before executing the component

  function piecesPlacement() {
    // placement each piece in specific house
    boardHousesArray.forEach((housesItem) => {
      if (!housesItem.isEmpty) {
        allPieces.forEach((piecesItem) => {
          if (
            piecesItem.startCords.cordX === housesItem.cordX &&
            piecesItem.startCords.cordY === housesItem.cordY
          ) {
            housesItem.starterPiece = piecesItem;
          }
        });
      }
    });
  }

In the bottom component, the chessboard is supposed to be built based on the array whose objects were merged in the above function. But the point here is that the objects must be merged before rendering

export default function Board() {
  const context = useContext(MainContext);
  return (
    // style dehi grid flex ba tavajoh be position khooneha
    // iani kolle khoonehaee ke a daran mian too ie sotoon
    <div className="chess-board-container">
      <ul className="chess-houses-container">
        {context.boardHousesArray.startPieces &&
          context.boardHousesArray.reverse().map((item) => (
            <li key={item.id} className={item.classes}>
              {item.id}
              {item.starterPiece}
            </li>
          ))}
      </ul>
    </div>
  );
}

I called function in useEffect , useMemo and so on but didnt work

export default function Board() {
  const context = useContext(MainContext);
  useEffect(() => {
    context.piecesPlacement();
  }, []);
  return (
    // style dehi grid flex ba tavajoh be position khooneha
    // iani kolle khoonehaee ke a daran mian too ie sotoon
    <div className="chess-board-container">
      <ul className="chess-houses-container">
        {context.boardHousesArray.startPieces &&
          context.boardHousesArray.reverse().map((item) => (
            <li key={item.id} className={item.classes}>
              {item.id}
              {item.starterPiece}
            </li>
          ))}
      </ul>
    </div>
  );
}

2

Answers


  1. The function piecesPlacement() is not being called before the component is rendered. This is because the function is being called inside the useEffect() hook, which is only called when the component’s state changes.

    To fix this, you need to call the function outside of the useEffect() hook. You can do this by using the useState() hook to create a state variable that stores the value of piecesPlacement(). Then, in the useEffect() hook, you can use the state variable to determine whether or not to call the function.

    Here is an example of how to do this:

    import React, { useState, useEffect } from "react";
    ​
    const Board = () => {
      const [piecesPlacement, setPiecesPlacement] = useState(false);
    ​
      useEffect(() => {
        setPiecesPlacement(true);
      }, []);
    ​
      if (piecesPlacement) {
        return (
          // style dehi grid flex ba tavajoh be position khooneha
          // iani kolle khoonehaee ke a daran mian too ie sotoon
          <div className="chess-board-container">
            <ul className="chess-houses-container">
              {context.boardHousesArray.startPieces &&
                context.boardHousesArray.reverse().map((item) => (
                  <li key={item.id} className={item.classes}>
                    {item.id}
                    {item.starterPiece}
                  </li>
                ))}
            </ul>
          </div>;
      } else {
        return null;
      }
    };
    

    This code will first call the function piecesPlacement() when the component is first rendered. Then, it will check the value of the state variable piecesPlacement to see if the function has been called. If the function has been called, then the component will render the chessboard. If the function has not been called, then the component will render nothing.

    Login or Signup to reply.
  2. so if i understand right, you are trying to merge two object in the picesPlacement() and then use the merged data to render the chessboard in the Board.

    1. Ensure that the picesPlacement() is correctly updating the context.boardHousesArray with the merged data. it seems that you are assigning the picesItem to housesItem.starterPice, but the code provided doesn’t show how boardHousesArray and allPicesare defined and populated. Make sure to check for correct data before calling the picesPlacement() function.
    2. Instead of modifying directly the context.boardHousesArray in the picesPlacement(), it’s better to create a new array and update the context with that new array (it prevents potential side effects).

    so:

    function piecesPlacement() {
      const updatedHousesArray = boardHousesArray.map((housesItem) => {
        if (!housesItem.isEmpty) {
          const matchedPiece = allPieces.find(
            (piecesItem) =>
              piecesItem.startCords.cordX === housesItem.cordX &&
              piecesItem.startCords.cordY === housesItem.cordY
          );
          return {
            ...housesItem,
            starterPiece: matchedPiece || null,
          };
        }
        return housesItem;
      });
    
      return updatedHousesArray;
    }
    

    Update the useEffect hook in the Board component

    export default function Board() {
      const context = useContext(MainContext);
    
      useEffect(() => {
        const updatedHousesArray = piecesPlacement();
        context.setBoardHousesArray(updatedHousesArray); // Assuming you have a setter function for boardHousesArray in MainContext
      }, []);
    
      return (
        <div className="chess-board-container">
          <ul className="chess-houses-container">
            {context.boardHousesArray.map((item) => (
              <li key={item.id} className={item.classes}>
                {item.id}
                {item.starterPiece}
              </li>
            ))}
          </ul>
        </div>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search