You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复cannot read properties of null (reading 'useContext')及无效Hook调用报错?

React Hook调用错误与代码修复

问题与错误信息

无法读取null的属性'useContext' && react.development.js:209 警告:无效的Hook调用。Hooks只能在函数组件的主体内部调用。可能的原因如下:

  1. React和渲染器(比如React DOM)版本不匹配
  2. 违反了Hooks的规则
  3. 同一个应用中有多个React副本

现有代码文件

App.js

function App() {
  return (  
    <React.Fragment> 
      <Counter/>
    </React.Fragment> 
  );
}

export default App;

index.js

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider context={StoreContext} store={Store()}>
    <App />
  </Provider>
);

reportWebVitals();

CounterReducer.js

const CounterReducer = (state = { count: 0 } , action) => {
  switch (action.type) {
    case handleDencrement:
      return state.count - 1 
            
    case handleIncrement:
      return state.count + 1
    
    default:
      return state
  } 
}

export default CounterReducer; 

context.js

const StoreContext = React.createContext();

export default StoreContext ;

Store.js

const Store = () => {
  const store = useStore(CounterReducer); 

  return store
}
export default Store;

types.js

export const handleIncrement = 'handleIncrement' ;

export const handleDencrement = 'handleDencrement';

Counter.js

const Counter = () => {
  const [count, setcount] = useState(0);

  const handleIncrement = () => {  
    setcount(count + 1);
  }

  const handleDencrement = () => {  
    setcount(count - 1);
  }

  return (
    <div>
      <center>
        <h1>Redux</h1>
        <h1>{count}</h1>
        <button className="btn btn-primary" onClick={handleIncrement}>Increment</button>
        <button className="btn btn-warning" onClick={handleDencrement}>decrement</button>
      </center>
    </div>
  );
}
export default Counter;

错误根源与修复方案

1. 违反Hook调用规则

Store.js中的Store函数包含Hook调用,绝对不能在组件外部直接执行。你在index.js里直接写store={Store()},相当于在React组件渲染流程之外调用了Hook(useStore),直接触发了无效Hook调用的警告。

2. Context Provider使用错误

你用了<Provider>,但React Context的Provider应该是StoreContext.Provider,并且通过value属性传递数据,而不是context和store属性。

3. Reducer返回值错误

CounterReducer里的返回值是数字(比如state.count -1),这会把原本的对象状态{count:0}覆盖成数字,后续再访问state.count就会报错(数字没有count属性),必须返回完整的状态对象。

4. 未正确关联状态与组件

Counter组件目前用的是自己的useState,完全没用到你定义的Context/Reducer,等于状态管理逻辑和组件脱节。


完整修复后的代码示例

修复Store.js(改成自定义Hook)

import { useReducer } from 'react';
import CounterReducer from './CounterReducer';

export const useStore = () => {
  const [state, dispatch] = useReducer(CounterReducer, { count: 0 });
  return { state, dispatch };
}

修复index.js(正确使用Context Provider)

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import StoreContext from './context';
import { useStore } from './Store';

// 用组件包裹,在内部调用Hook
const RootWrapper = () => {
  const store = useStore();
  return (
    <StoreContext.Provider value={store}>
      <App />
    </StoreContext.Provider>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<RootWrapper />);

reportWebVitals();

修复CounterReducer.js(返回完整状态对象)

import { handleIncrement, handleDencrement } from './types';

const CounterReducer = (state = { count: 0 }, action) => {
  switch (action.type) {
    case handleDencrement:
      return { ...state, count: state.count - 1 };
    case handleIncrement:
      return { ...state, count: state.count + 1 };
    default:
      return state;
  }
};

export default CounterReducer;

修复Counter.js(使用Context获取状态和dispatch)

import { useContext } from 'react';
import StoreContext from './context';
import { handleIncrement, handleDencrement } from './types';

const Counter = () => {
  const { state, dispatch } = useContext(StoreContext);

  return (
    <div>
      <center>
        <h1>Redux风格状态管理</h1>
        <h1>{state.count}</h1>
        <button className="btn btn-primary" onClick={() => dispatch({ type: handleIncrement })}>Increment</button>
        <button className="btn btn-warning" onClick={() => dispatch({ type: handleDencrement })}>decrement</button>
      </center>
    </div>
  );
};

export default Counter;

内容的提问来源于stack exchange,提问作者Djamel Eddine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 12:10:56