【问题标题】:problem of alternating between two handler event functions在两个处理程序事件函数之间交替的问题
【发布时间】:2021-12-01 20:33:14
【问题描述】:

我有一个游戏反应匹配卡片项目要做。如果两个购物车内容相同,游戏包括在卡片网格中选择卡片,所以这两个购物车将是她的匹配属性,并将显示为绿色和分数组件将标记 2 张匹配的卡片,依此类推发布此功能,它在控制台中运行良好,但是当我在代码应用程序中尝试它时,它根本不起作用,请帮助我修复它,这是我的代码组件:

the boardSlice: 
const initialState = [
  {id: 0, contents: 'Provider', visible: true, matched: true}, 
  {id: 1, contents: 'Provider', visible: true, matched: true}, 
  {id: 2, contents: 'selector', visible: true, matched: true}, 
  {id: 3, contents: 'selector', visible: true, matched: true}, 
  {id: 4, contents: 'useSelector()', visible: true, matched: true}, 
  {id: 5, contents: 'useSelector()', visible: true, matched: true}, 
  {id: 6, contents: 'useDispatch()', visible: true, matched: true}, 
  {id: 7, contents: 'useDispatch()', visible: true, matched: true}, 
  {id: 8, contents: 'Pure Function', visible: true, matched: true}, 
  {id: 9, contents: 'Pure Function', visible: true, matched: true}, 
  {id: 10, contents: 'react-redux', visible: true, matched: true}, 
  {id: 11, contents: 'react-redux', visible: true, matched: true}, 
];

export const boardReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'board/setBoard':
      let setState = [];
      action.payload.forEach((element, index) => 
        setState.push({id: index, 
                      contents: element, 
                      visible: false, 
                      matched: false})
      );
      return setState;
         
    case 'board/flipCard':
      let flipState = [...state];
      const cardID = action.payload;
      flipState[cardID] = {...state[cardID], visible:true}
      const [index1, index2] = flipState.filter(card => card.visible).map(card => card.id);
      if (index2 !== undefined) {
        let card1 = flipState[index1];
        let card2 = flipState[index2];
        if (card1.contents === card2.contents) {
          flipState[index1] = {...card1, visible: false, matched: true};
          flipState[index2] = {...card2, visible: false, matched: true};
        }
      }
    return flipState;
 case 'board/resetUnmatchedCards':
  let newState = [...state];
  let [indexa, indexb] = newState.filter(card => card.visible === true && card.matched === false).map(card => card.id);
  if (indexb !== undefined) {
    let cardA = newState[indexa];
    let cardB = newState[indexb];
    newState[indexa] = {...cardA, visible: action.payload};
    newState[indexb] = {...cardB, visible: action.payload}
  }
  return newState
    case 'board/resetCards':
      return state.map(card => ({...card, visible: false}));
    
    default:
      return state;
  }
}

const wordPairs = [
  'Provider', 'Provider', 
  'selector', 'selector', 
  'useSelector()', 'useSelector()', 
  'useDispatch()', 'useDispatch()',
  'Pure Function', 'Pure Function',
  'react-redux', 'react-redux',
]

const randomWords = () => {
  let words = []
  let newWordPairs = [...wordPairs]
  const reps = newWordPairs.length
  for (let i = 0 ; i < reps ; i++) {
    const wordIndex = Math.floor(Math.random() * newWordPairs.length);
    words.push(newWordPairs[wordIndex])
    newWordPairs.splice(wordIndex, 1)
  }

  return words;
} 

// action creators
export const setBoard = () => {
  const words = randomWords()
  return {
    type: 'board/setBoard',
    payload: words
  }
}

export const flipCard = (id) => {
  return {
    type: 'board/flipCard',
    payload: id
  }
}

export const resetCards = (indices) => {
  return {
    type: 'board/resetCards'
  }
};
export const resetUnmatchedCards = () => {
  return {
    type: 'board/resetUnmatchedCards',
    payload: false
  }
}

// Add selector export statments below
export const selectBoard = (state) => { 
  return ( state.board.map(card=> 
  ({
    id: card.id,
    contents: card.contents
  })
  
  ))}
export const selectVisibleIDs = state => {
  return (
    state.board.filter(card => card.visible)
    .map(card => card.id)
  )
}
export const selectMatchedIDs = state => {
  return ( state.board.filter(card => card.matched)
  .map(card => card.id));
};


the App component :
import './App.css';
import React from 'react';
import { Score } from './features/score/Score.js';
import { Board } from './features/board/Board.js';
import { useDispatch } from 'react-redux';
import { setBoard, resetCards } from './features/board/boardSlice';

// Add import statements below



const App = () => {
  // Add dispatch variable below
  const dispatch = useDispatch();

  const startGameHandler = () => {
    // Add action dispatch below
    dispatch(setBoard())
  };

  const tryAgainHandler = () => {
    // Add action dispatch below
    dispatch(resetCards())
  };

  return (
    <div className="App">
      <Score />
      <Board />
      <footer className="footer">
        <button onClick={startGameHandler} className="start-button">
          Start Game
        </button>
        <button onClick={tryAgainHandler} className="try-new-pair-button">
          Try New Pair
        </button>
      </footer>
    </div>
  );
};

export default App;

the board component :
import React from 'react';
import { CardRow } from './cardRow/CardRow.js';
// Add import statements below
import { useSelector } from 'react-redux';
import { selectBoard } from './boardSlice';


export const Board = () => {
  // Add selected data variable and implement below
  const currentBoard = useSelector(selectBoard);

  const numberOfCards = currentBoard.length;
  const columns = 3;
  const rows = Math.floor(numberOfCards / columns);

  const getRowCards = (row) => {
    const rowCards = [];
    for (let j = 0; j < columns; j++) {
      const cardIndex = row * columns + j;
      // Implement selected data below
      rowCards.push(currentBoard[cardIndex]);
    }
    return rowCards;
  };
console.log(currentBoard)
  let content = [];
  for (let row = 0; row < rows; row++) {
    const rowCards = getRowCards(row);
    content.push(
      <CardRow 
        key={row} 
        cards={rowCards} 
      />
    );
  }
  return <div className="cards-container">{content}</div>;
};

the cardRow.js:
import React from 'react';
import { Card } from './card/Card.js';
import {selectMatchedIDs } from '../boardSlice'
export const CardRow = ({ cards }) => {
  const content = cards.map(card => 
    <Card 
      key={card.id} 
      id={card.id} 
      contents={card.contents} 
     
  />)

  return <>{content}</>;
};


the Card.js:
import React, {useEffect} from 'react';
// Add import statements below

import { useSelector, useDispatch } from 'react-redux';
import { selectVisibleIDs, flipCard, selectMatchedIDs,  } from '../../boardSlice';
import { resetCards, resetUnmatchedCards } from '../../boardSlice'
let cardLogo = "https://static-assets.codecademy.com/Courses/Learn-Redux/matching-game/codecademy_logo.png";

export const Card = ({ id, contents }) => {
  // Add selected data and dispatch variables below
  const visibleIDs = useSelector(selectVisibleIDs) 
  const dispatch = useDispatch();
  const matchedIDs = useSelector(selectMatchedIDs);
console.log(visibleIDs)
console.log(matchedIDs);

  // flip card action
  const flipHandler = (id) => {
    // Add action dispatch below
    dispatch(flipCard(id))
    
  };
  const resetHandler = () => {
    dispatch(resetUnmatchedCards)
  }

  let cardStyle = 'resting';
 
  let click = () => flipHandler(id);
 
  let cardText = (
    <img src={cardLogo} className="logo-placeholder" alt="Card option" />
  );

  // 1st if statement
  // implement card id array membership check
  if (visibleIDs.includes(id) || matchedIDs.includes(id)) { 
  

    cardText = contents;
    click = () => {};
  } 
  
  // 2nd if statement
  // implement card id array membership check
  if (matchedIDs.includes(id)) {
    

  cardStyle = 'matched';
  
  } else { 
 cardStyle = 'no-match';
  
  }

  // 3rd if statement
  // implement number of flipped cards check
  if (visibleIDs.length === 2) {
    if (cardStyle === 'no-match' ) {
    click = () => resetHandler(); 
    }
    click = ()=> {};
    
  }

  return (
    <button onClick={click} className={`card ${cardStyle}`}>
      {cardText}
    </button>
  );
};

【问题讨论】:

  • 请格式化您的问题,使其更具可读性。整段是一句话,我真的不明白你在问什么。另请尝试仅包含与您遇到的问题相关的代码。
  • 好吧,我的朋友,你是对的

标签: javascript redux javascript-objects


【解决方案1】:

所以问题是我想将点击按钮更改为其他功能,以便首先每张卡片都有这个对象 {id:cardId, contents: cardContents, visible: false, match: false} 所以首先当用户通过“FlipCard”操作单击两张卡片 card.visible 变为真,那么如果第一张 card.contents 与第二张 card.contents 相同,那么两张卡片的 card.matched 属性将变为真,所以我需要的东西当第一个 card.contents 与第二个 card.contents 不同时,想添加另一个函数来将两个 card.visible 重置为 false 所以这是我的组件 Card 代码:

import React, {useEffect} from 'react';
// Add import statements below

import { useSelector, useDispatch } from 'react-redux';
import { selectVisibleIDs, flipCard, selectMatchedIDs,  } from '../../boardSlice';
import { resetCards, resetUnmatchedCards } from '../../boardSlice'
let cardLogo = "https://static-assets.codecademy.com/Courses/Learn-Redux/matching-game/codecademy_logo.png";

export const Card = ({ id, contents }) => {
  // Add selected data and dispatch variables below
  const visibleIDs = useSelector(selectVisibleIDs) 
  const dispatch = useDispatch();
  const matchedIDs = useSelector(selectMatchedIDs);

console.log(matchedIDs);

  // flip card action
  const flipHandler = (id) => {
    // Add action dispatch below
    dispatch(flipCard(id))
    
  };
  const resetHandler = () => {
    dispatch(resetCards)
  }

  let cardStyle = 'resting';
 
  let click = () => flipHandler(id);
 
  let cardText = (
    <img src={cardLogo} className="logo-placeholder" alt="Card option" />
  );

  // 1st if statement
  // implement card id array membership check
  if (visibleIDs.includes(id) || matchedIDs.includes(id)) { 
  

    cardText = contents;
    click = () => {};
  } 
  
  // 2nd if statement
  // implement card id array membership check
  if (matchedIDs.includes(id)) {
    

  cardStyle = 'matched';
  
  } else { 
 cardStyle = 'no-match';
  
  }
console.log(visibleIDs.every(id => matchedIDs.includes(id)))
  // 3rd if statement
  // implement number of flipped cards check
  if (visibleIDs.length === 2 ) {
  if (cardStyle === 'no-match'  && visibleIDs.every(id => !matchedIDs.includes(id))) {
    
    click = () => resetHandler(); 
    } else {
    
    click = () => {};
    }
 
    }

  return (
    <button onClick={click} className={`card ${cardStyle}`}>
      {cardText}
    </button>
  );
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-16
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 2016-01-07
    • 2018-08-18
    • 2011-11-03
    相关资源
    最近更新 更多