首页 > 解决方案 > (React,Redux)当我将调度代码放入我的 onChange 函数时发生错误

问题描述

当我在我的组件中放置一个包含调度的函数时,会出现错误消息。

我检查了 err msg 给我的链接。我有正确的反应版本,不确定其他条件。(打破 Hooks 的规则你只能在 React 渲染一个函数组件时调用 Hooks:

✅ 在函数组件主体的顶层调用它们。✅ 在自定义 Hook 主体的顶层调用它们。)

并且组件可以在没有调度代码的情况下正常工作。

这是父组件(这很好用)

import React, { Component } from 'react';
import { Jumbotron } from 'react-bootstrap';
import { Route, NavLink } from 'react-router-dom';
import { Seoul, Gyeongi, Incheon, Busan, Daegue, Daejeon, Sejong, Gwangju, Ulsan, Gangwon, Gyungnam, Gyungbuk, Jeonnam, Jeonbuk, Choongnam, Choongbuk, Jeju, Othercountry } from './Locals/localbox';
import './Detailsrch.css';

class Detailsrch extends Component {
    constructor(props){
        super(props);
    }
    render() {
        var localselect = (e) => {
            console.log(e.target.getAttribute('name'));
            let selector = document.getElementsByClassName('locals');
            let selector_local = document.getElementsByClassName('localdiv');
            let i = 0;
            for (let j=0; j<selector_local.length; j++) {
                selector_local[j].style.display = 'none';
              }
            let boxclass = e.target.getAttribute('name');
            document.getElementsByClassName(boxclass)[0].style.display = 'block';
            while (selector[i]) {
                selector[i].className = 'locals';
                i++;
            }
            if(e.target.className=='localtext'){
                e.target.parentElement.className = 'locals localclick';
            } else {
                e.target.className = 'locals localclick';
            }
        }
        return (
            <Jumbotron className='searchjumbo'>
                <p>지역&lt;/p>
                <ul>
                    <li className='locals' onClick={localselect}><span className='localtext'>전체</span></li>
                    <li className='locals' onClick={localselect} name='localdiv1'><span className='localtext' name='localdiv1'>서울</span></li>
                    <li className='locals' onClick={localselect} name='localdiv2'><span className='localtext' name='localdiv2'>경기</span></li>
                    <li className='locals' onClick={localselect} name='localdiv3'><span className='localtext' name='localdiv3'>인천</span></li>
                    <li className='locals' onClick={localselect} name='localdiv4'><span className='localtext' name='localdiv4'>부산&lt;/span></li>
                    <li className='locals' onClick={localselect} name='localdiv5'><span className='localtext' name='localdiv5'>대구&lt;/span></li>
                    <li className='locals' onClick={localselect} name='localdiv6'><span className='localtext' name='localdiv6'>대전&lt;/span></li>
                    <li className='locals' onClick={localselect} name='localdiv7'><span className='localtext' name='localdiv7'>세종</span></li>
                    <li className='locals' onClick={localselect} name='localdiv8'><span className='localtext' name='localdiv8'>광주</span></li>
                    <li className='locals' onClick={localselect} name='localdiv9'><span className='localtext' name='localdiv9'>울산</span></li>
                    <li className='locals' onClick={localselect} name='localdiv10'><span className='localtext' name='localdiv10'>강원</span></li>
                    <li className='locals' onClick={localselect} name='localdiv11'><span className='localtext' name='localdiv11'>경남</span></li>
                    <li className='locals' onClick={localselect} name='localdiv12'><span className='localtext' name='localdiv12'>경북</span></li>
                    <li className='locals' onClick={localselect} name='localdiv13'><span className='localtext' name='localdiv13'>전남</span></li>
                    <li className='locals' onClick={localselect} name='localdiv14'><span className='localtext' name='localdiv14'>전북</span></li>
                    <li className='locals' onClick={localselect} name='localdiv15'><span className='localtext' name='localdiv15'>충남</span></li>
                    <li className='locals' onClick={localselect} name='localdiv16'><span className='localtext' name='localdiv16'>충북</span></li>
                    <li className='locals' onClick={localselect} name='localdiv17'><span className='localtext' name='localdiv17'>제주</span></li>
                    <li className='locals' onClick={localselect} name='localdiv18'><span className='localtext' name='localdiv18'>해외</span></li>
                </ul>
                <Seoul/>
                <Gyeongi/>
                <Incheon/>
                <Busan/>
                <Daegue/>
                <Daejeon/>
                <Sejong/>
                <Gwangju/>
                <Ulsan/>
                <Gangwon/>
                <Gyungnam/>
                <Gyungbuk/>
                <Jeonnam/>
                <Jeonbuk/>
                <Choongnam/>
                <Choongbuk/>
                <Jeju/>
                <Othercountry/>
                <hr className='firsthr' />
                <p>형태</p><hr />

                <p>경력</p><hr />

                <p>국적</p><hr />

                <p>성별</p>
            </Jumbotron>
        );
    }
};

这是问题所在的代码。

import React, { Component } from 'react';
import { ToggleButton, ToggleButtonGroup } from 'react-bootstrap'
import { useSelector, useDispatch } from 'react-redux';
import { checked, notchecked } from '../../../actions';
import './localbox.css';
const dispatch = useDispatch();


export class Seoul extends Component {
    constructor(props){
        super(props);
    }
    render() {
        /* var btnclicked = (e) => {
            let btnname = e.target.getAttribute('name');
            if (e.target.children[0].checked = true) {
                return () => dispatch(checked(btnname));
            } else if (e.target.children[0].checked = false) {
                return () => dispatch(notchecked(btnname));
            };
        }; Here is my functino for onChange */
        // when I get rid of above code, this works fine.
        return (
            <div className='localdiv localdiv1'>
                <ToggleButtonGroup className='togglebtngrp' type="checkbox">
                    <ToggleButton className='togglebtn0' variant="outline-secondary" value={0} >전체</ToggleButton>
                    <ToggleButton className='togglebtn' onChange={btnclicked} name="강남구" variant="outline-primary" value={1}>강남구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={2}>강동구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={3}>강북구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={4}>강서구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={5}>관악구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={6}>광진구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={7}>구로구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={8}>금천구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={9}>노원구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={10}>도봉구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={11}>동대문구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={12}>동작구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={13}>마포구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={14}>서대문구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={15}>서초구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={16}>성동구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={17}>성북구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={18}>송파구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={19}>양천구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={20}>영등포구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={21}>용산구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={22}>은평구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={23}>종로구&lt;/ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={24}>중구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={25}>중랑구&lt;/ToggleButton>
                </ToggleButtonGroup>
            </div>
        )
    }
};

我希望如果我单击 ToggleButton,onChange 事件将激活并且函数 btncliked 将被执行。

但它一直告诉我无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一: 1. 你可能有不匹配的 React 版本和渲染器(例如 React DOM) 2. 你可能违反了 Hooks 规则 3. 你可能有多个 React 副本同一个应用程序... . . ..

在此处输入图像描述

标签: reactjsredux

解决方案


您在React 函数组件之外使用 Hook 。

const dispatch = useDispatch();

您应该使用函数组件来使用钩子并将其useDispatch放置在函数内部:

const Seoul = () => {
  const dispatch = useDispatch();

  var btnclicked = (e) => {
    let btnname = e.target.getAttribute('name');

    if (e.target.children[0].checked = true) {
      return () => dispatch(checked(btnname));
    } else if (e.target.children[0].checked = false) {
      return () => dispatch(notchecked(btnname));
    };
  };  


  return (
    <div className='localdiv localdiv1'>
      ...
    </div>
  );
};


推荐阅读