【问题标题】:(React, Redux) Error occurs when I put my dispatch code in my onChange function(React,Redux)当我将调度代码放入我的 onChange 函数时发生错误
【发布时间】:2019-07-29 08:53:53
【问题描述】:

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

我检查了 err msg 给我的链接。 我有正确的反应版本,但不确定其他条件。 (打破钩子的规则 你只能在 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>지역</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'>부산</span></li>
                    <li className='locals' onClick={localselect} name='localdiv5'><span className='localtext' name='localdiv5'>대구</span></li>
                    <li className='locals' onClick={localselect} name='localdiv6'><span className='localtext' name='localdiv6'>대전</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}>강남구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={2}>강동구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={3}>강북구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={4}>강서구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={5}>관악구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={6}>광진구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={7}>구로구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={8}>금천구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={9}>노원구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={10}>도봉구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={11}>동대문구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={12}>동작구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={13}>마포구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={14}>서대문구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={15}>서초구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={16}>성동구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={17}>성북구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={18}>송파구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={19}>양천구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={20}>영등포구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={21}>용산구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={22}>은평구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={23}>종로구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={24}>중구</ToggleButton>
                    <ToggleButton className='togglebtn' variant="outline-primary" value={25}>중랑구</ToggleButton>
                </ToggleButtonGroup>
            </div>
        )
    }
};

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

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

【问题讨论】:

    标签: reactjs redux


    【解决方案1】:

    您正在使用 React function component 之外的 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>
      );
    };
    
    

    【讨论】:

    • 遗憾的是,在您编写代码时,该代码一开始就在那里。我没有写它是我的错。但当时也有同样的错误信息。我再次移动它以确保它仍然无法正常工作。我会在我的问题中更新 err msg。
    • 好吧,事实证明,如果我不使用 class Seoul extends Component 并将其替换为您所写的 const ,它就可以正常工作。你能告诉我它们之间的区别以及为什么 Component 不起作用?我还是不明白:(
    • Hooks 只能在 Function 组件中使用(无类)。这是钩子的规则之一。 :-) 看看我提供的链接,那里解释得很好。
    猜你喜欢
    • 1970-01-01
    • 2011-09-26
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    相关资源
    最近更新 更多