首页 > 解决方案 > 如何在 React 函数中调用自定义 Hook

问题描述

我正在我的项目中处理一个 React 项目 我有一个自定义钩子,现在我试图在一个函数中调用该自定义钩子,但它显示错误,例如在函数“applyStyle”中调用了这个 React Hook“useMediaQuery”,既不是一个 React 函数组件,也不是一个自定义的 React Hook 函数。React 组件名称必须以大写字母开头

所以有人帮我解决这个问题

这是我的代码

这是 App.js

import React, { useState, useLayoutEffect } from 'react';
import './App.css';


const App = () => {
    const [style, setStyle] = useState(null)


    function useMediaQuery() {
        const [screenSize, setScreenSize] = useState([0]);
        
        useLayoutEffect(() => {
          function updateScreenSize() {
            setScreenSize([window.innerWidth]);
          }
          window.addEventListener("resize", updateScreenSize);
          updateScreenSize();
          return () => window.removeEventListener("resize", updateScreenSize);
        }, []);
        
        return screenSize;
      }

      const applyStyle = () => {
          if(useMediaQuery() === 320) {
              setStyle({
                  marginBottom: '150px'
              })
          }
      }

return (
        <div className='container'>
            <div className='row'>
                <div className='col-12'>
                    <div className='first'>
                        <button onClick={applyStyle} style={style}  className='btn btn-primary'>Click here</button>
                        <span className='closeWindow'><i className="far fa-window-close"></i></span>
                    </div>
                    <div className='second'>
                    </div>
                </div>
            </div>
        </div>
    )
}

export default App

````

标签: reactjs

解决方案


我想你忘记了钩子的两条最重要的规则

它说

仅从 React 函数组件调用 Hooks。不要从常规 JavaScript 函数调用 Hooks。(还有一个有效的地方可以调用 Hooks——你自己的自定义 Hooks。我们稍后会了解它们。)

所以你的情况应该是:

import React, { useState, useLayoutEffect } from 'react';
import './App.css';


const App = () => {
    const [style, setStyle] = useState(null)


    function useMediaQuery() {
        const [screenSize, setScreenSize] = useState([0]);
        
        useLayoutEffect(() => {
          function updateScreenSize() {
            setScreenSize([window.innerWidth]);
          }
          window.addEventListener("resize", updateScreenSize);
          updateScreenSize();
          return () => window.removeEventListener("resize", updateScreenSize);
        }, []);
        
        return screenSize;
      }
      
      const mediaQuery = useMediaQuery();

      const applyStyle = () => {
          if(mediaQuery === 320) {
              setStyle({
                  marginBottom: '150px'
              })
          }
      }

return (
        <div className='container'>
            <div className='row'>
                <div className='col-12'>
                    <div className='first'>
                        <button onClick={applyStyle} style={style}  className='btn btn-primary'>Click here</button>
                        <span className='closeWindow'><i className="far fa-window-close"></i></span>
                    </div>
                    <div className='second'>
                    </div>
                </div>
            </div>
        </div>
    )
}

export default App

推荐阅读