0

Here you can see the instructions box>I am working on a fairly simple rock, paper, and scissor game to familiarize myself with React and React Styled Components. At the beginning there is a container "Rules" that pops up with the instructions of the game. By means of a button one can see or not the container with the rules later. For now the event handler of the button changes the opacity state of my container. However the component is still clearly there. I need that after passing its opacity from '1' to '0' in a time of '2s' by a transition the component passes its display property from "grid" to "none". If someone can help me I would appreciate it very much.

APP.JS

function App() {
      useEffect( () => {
        changeDisplay();
      }, [])
    
      const [opacity, setOpacity] = useState('0.5');
      const [display, setDisplay] = useState(true);
      const [rules, setRules] = useState(true);
    
      const changeDisplay = (displayValue) => {
        if(!displayValue){
          setDisplay(displayValue)
          setOpacity('0.5')
        }else if(displayValue){
          setDisplay(displayValue)
          setOpacity('1')
        }
      }
    
      const rulesSet = () => {
        if(rules){
          setRules(false)
        } else {
          setRules(true)
        }
      }
    
      return (
        <div id='backgroundImg'>
        <ExternalWrapper>
          <InternalWrapper opacity={opacity}>
            <LogoAndScore/>
            <Options></Options>
            <div  id="rulesButton" onClick={rulesSet}><h2>RULES</h2></div>
          </InternalWrapper>
            <Rules changeDisplay={changeDisplay} rules={rules}/>
        </ExternalWrapper>
        </div>
      );
}
    
export default App;

RULES.JS

const WrapperRules = styled.div`
    transition: ease-out 500ms;
    background-color:white;
    border-radius:2rem;
    z-index:10;
    display:${props => props.display};
    grid-template-columns:1fr;
    grid-template-rows:60px 270px;
    height:fit-content;
    padding:30px;
    paddin-top:-20px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, ${props => props.translate});
    opacity:${props => props.opacity}
    `
    
const WrapperX = styled.div`
    grid-row-start:1;
    grid-columnStart:1 ;
    width:fit-content ;
    margin:0px;
    justify-self:right ;
    align-self:start ;
    height:15px;
    transition:500ms;
    
    &:hover{
      transform:scale(1.2)
    }
    `
    
const Rules = ({ changeDisplay, rules }) => {
    
      const [opacity, setOpacity] = useState('0.1')
    
      useEffect(() => {
        hideRules()
      }, [rules])
    
      const [translate, setTranslate] = useState('-20%')
      const [display, setDisplay] = useState('grid')
    
      const hideRules = () => {
        opacity === '1' ? setOpacity('0') : setOpacity('1')
        translate === '-50%' ? setTranslate('-20%') : setTranslate('-50%')
        opacity === '1' ? changeDisplay(true) : changeDisplay(false);
      }
    
      return (HERE IT RENDER RULES)
    
}
    
export default Rules;
Emre Koc
  • 1,481
  • 10
  • 18

1 Answers1

0

I'd suggest adding useEffect(s) to switch the display to 'none' after the opacity transition has completed. Conversely, you will need to set the display property back to 'grid' before the opacity state changes from '0' to '1'. The additional code might look something like the following:

const Rules = ({ changeDisplay, rules }) => {

...

  useEffect(() => {
    if (opacity === '0') {
      setTimeout(() => {
        setDisplay('none');
      }, 500)
    }
  }, [opacity]);

  useEffect(() => {
    if (rules) {
      setDisplay('grid');
      setTimeout(() => {
        hideRules();
      });
    } else if (!rules) {
      hideRules();
    }
  }, [rules])

  ...
}
EvanMorrison
  • 1,212
  • 8
  • 13