簡體   English   中英

Javascript 在安裝組件時反應 function

[英]Javascript in react function when component is mounted

我的鍵盤可以工作,但現在我正在為 state 處理實施 redux。 我的舊版本用作 class 組件,並且在 componentDidMount 上調用了 javascript function。 現在這不再是一個選項,因為我現在需要將其轉換為 function 以使其與 redux 的調度一起使用。 我嘗試將 javascript 放在 return 下並將其稱為單獨的 function 兩者都沒有做任何事情。 有沒有辦法做到這一點?

import React from 'react';
import '../../style/App.scss';
import $ from "jquery";
import { UPDATE_GAME_STATE } from '../../actions'
import { useDispatch } from 'react-redux';

function Keypad(){
  init_keypad();
  return(
  <div className="keypad_wrapper">
    <div className="screen"></div>
    <div className="error notification">ERROR</div>
    <div className="success notification">SUCCESS</div>

    <div className="key">1</div>
    <div className="key">2</div>
    <div className="key">3</div>
    <div className="key">4</div>
    <div className="key">5</div>
    <div className="key">6</div>
    <div className="key">7</div>
    <div className="key">8</div>
    <div className="key">9</div>
    <div className="key last">0</div>
  </div>
);
}
export default Keypad;


function init_keypad(){
  const dispatch = useDispatch();
  window.tries = 0;
  $(".key").click(function(){
    var n = $(this).html();
    $('.screen').append( n );
    window.tries++;
    // if 4 digits are entered check if its correct
    if (window.tries >= 4){
      var w = $('.screen').html();
      if (w == 1234){
        $('.success').show().delay(5000).queue(function(n) {
          $('.success').hide(); n();
          dispatch(UPDATE_GAME_STATE('playing'));
        });
      }
      else{
        $('.error').show().delay(1000).queue(function(n) {
          $('.error').hide(); n();
        });
      }
      $('.screen').html('');
      window.tries = 0;
    }
  });
}

錯誤消息現在是這樣的:

React Hook "useDispatch" 在 function "init_keypad" 中調用,它既不是 React function 組件,也不是自定義 React Hook ZC1C425268E68385D14AB5074C17A9

首先,您需要在 React 組件中使用useDispatch而不是普通的 function ,在這種情況下是Keypad

您需要將其包裝在 useEffect 中,因為它相當於 class 組件中的 componentDidMount

import React, { useEffect } from "react";

function Keypad(){
   useEffect(() => {
      init_keypad();
   }, []);

   return (
    ...
   );
}

您需要在反應組件中使用鈎子,這在您使用 useDispatch 時不會發生,所以在這里您可以通過兩種方式將init_keypad作為反應功能組件,然后使用useDispatch或者簡單地從Keypad傳遞useDipatch

import React from 'react';
import '../../style/App.scss';
import $ from "jquery";
import { UPDATE_GAME_STATE } from '../../actions'
import { useDispatch, useEffect } from 'react-redux';

function Keypad(){
  const dispatch = useDispatch();
   useEffect(() => {
     init_keypad(dispatch);
   }, []);      
return(
  <div className="keypad_wrapper">
    <div className="screen"></div>
    <div className="error notification">ERROR</div>
    <div className="success notification">SUCCESS</div>

    <div className="key">1</div>
    <div className="key">2</div>
    <div className="key">3</div>
    <div className="key">4</div>
    <div className="key">5</div>
    <div className="key">6</div>
    <div className="key">7</div>
    <div className="key">8</div>
    <div className="key">9</div>
    <div className="key last">0</div>
  </div>
);
}
export default Keypad;


function init_keypad(dispatch){
  window.tries = 0;
  $(".key").click(function(){
    var n = $(this).html();
    $('.screen').append( n );
    window.tries++;
    // if 4 digits are entered check if its correct
    if (window.tries >= 4){
      var w = $('.screen').html();
      if (w == 1234){
        $('.success').show().delay(5000).queue(function(n) {
          $('.success').hide(); n();
          dispatch(UPDATE_GAME_STATE('playing'));
        });
      }
      else{
        $('.error').show().delay(1000).queue(function(n) {
          $('.error').hide(); n();
        });
      }
      $('.screen').html('');
      window.tries = 0;
    }
  });
}

您可以使用“useEffect”掛鈎將其用作 componentDidMount 等效項,並避免使用 window object 來跟蹤計數,而是使用“useRef”掛鈎,如下所示

    import React from 'react';
    import '../../style/App.scss';
    import $ from "jquery";
    import { UPDATE_GAME_STATE } from '../../actions'
    import { useDispatch } from 'react-redux';

    function Keypad() {
        const dispatch = useDispatch();
        const tries = React.useRef(0);

        React.useEffect(() => {
            $(".key").click(function () {
                var n = $(this).html();
                $('.screen').append(n);
                tries.current++;
                // if 4 digits are entered check if its correct
                if (tries.current >= 4) {
                    var w = $('.screen').html();
                    if (w == 1234) {
                        $('.success').show().delay(5000).queue(function (n) {
                            $('.success').hide(); n();
                            dispatch(UPDATE_GAME_STATE('playing'));
                        });
                    }
                    else {
                        $('.error').show().delay(1000).queue(function (n) {
                            $('.error').hide(); n();
                        });
                    }
                    $('.screen').html('');
                    tries.current = 0;
                }
            });
        }, []);

        return (
            <div className="keypad_wrapper">
                <div className="screen"></div>
                <div className="error notification">ERROR</div>
                <div className="success notification">SUCCESS</div>

                <div className="key">1</div>
                <div className="key">2</div>
                <div className="key">3</div>
                <div className="key">4</div>
                <div className="key">5</div>
                <div className="key">6</div>
                <div className="key">7</div>
                <div className="key">8</div>
                <div className="key">9</div>
                <div className="key last">0</div>
            </div>
        );
    }
    export default Keypad;

However, I would also like to suggest you not to use jQuery along with ReactJs, as main purpose of using ReactJs is lost as you directly manipulate/play with DOM objects using libraries such as jQuery.

將 jQuery 與 RaectJs 一起使用是一種不好的做法,因為 React 使用了一個稱為虛擬 DOM 的概念而不是實際的 DOM。 而且 React 不知道在這個 Virtual DOM 之外所做的更改。 當您使用 jQuery 或任何其他操作實際 DOM 的庫時,您的應用程序可能會導致 go 不同步。

If you want to use jQuery for AJAX purposes, you can just use a library specifically made for AJAX, like Axios or the native Fetch API.

並且不要忘記在卸載時刪除事件偵聽器,為此您可以在 useEffect 掛鈎中返回一個 function ,其行為類似於 componentWillUnmount 方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM