如何修复无法读取 null 的属性(读取“useContext”)?

Dja*_*ine 11 javascript reactjs redux react-redux

我找不到罪魁祸首在哪里。我尝试调试它,但找不到真正导致这些错误的原因:

无法读取 null 的属性(读取“useContext”)&&react.development.js:209 警告:无效的挂钩调用。钩子只能在函数组件的主体内部调用。发生这种情况可能是由于以下原因之一:

  1. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  2. 你可能违反了 Hooks 规则
  3. 您可能在同一个应用程序中拥有多个 React 副本

应用程序.js

function App() {
  return (  
    <React.Fragment> 
      <Counter/>
    </React.Fragment> 
  );
}
        
export default App;
Run Code Online (Sandbox Code Playgroud)

索引.js

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

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; 
Run Code Online (Sandbox Code Playgroud)

上下文.js

const StoreContext = React.createContext();
     
export default StoreContext ;
    
Run Code Online (Sandbox Code Playgroud)

商店.js

const Store = () => {
  const store = useStore(CounterReducer); 
      
  return store
}
export default Store;
    
Run Code Online (Sandbox Code Playgroud)

类型.js

export const handleIncrement = 'handleIncrement' ;
    
export const handleDencrement = 'handleDencrement';
    
Run Code Online (Sandbox Code Playgroud)

计数器.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;
Run Code Online (Sandbox Code Playgroud)

小智 6

我的问题已通过 Next.js 解决,只需使用“Ctrl + C”停止服务器即可。并使用“npm run dev”重新启动服务器。希望这可以帮助。

  • 通过额外的支持信息可以改进您的答案。请[编辑]添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以[在帮助中心](/help/how-to-answer)找到有关如何写出好的答案的更多信息。 (2认同)

Dre*_*ese 3

问题

Store不是 React 组件,因此它不能使用钩子useStore

useStore

该钩子返回对传递给组件的同一 Redux 存储的引用<Provider>

换句话说,该useStore钩子期望从 ReactTree 中的更高层向它提供 Redux Context。

解决方案

从我对代码的了解来看,您似乎希望该Store函数创建并返回一个 Redux 存储对象,并将其传递给Provider组件。

商店.js

import { createStore, combineReducers } from 'redux';
import counter from '../path/to/counter.reducer';

const rootReducer = combineReducers({
  counter,
});

const store = createStore(rootReducer);

export default store;
Run Code Online (Sandbox Code Playgroud)

类型

export const handleIncrement = 'handleIncrement' ;
export const handleDecrement = 'handleDecrement';
Run Code Online (Sandbox Code Playgroud)

counter.reducer.js

减速器函数应保持状态不变。在这种情况下,状态是一个具有count属性的对象。

const counterReducer = (state = { count: 0 }, action) => {
  switch (action.type) {
    case handleDecrement:
      return {
        ...state,
        count: state.count - 1
      }; 

    case handleIncrement:
      return {
        ...state,
        count: state.count + 1,
      };

    default:
      return state;
  }
};
Run Code Online (Sandbox Code Playgroud)

索引.js

...
import store from '../path/to/store';
...

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);
Run Code Online (Sandbox Code Playgroud)

柜台

组件不应使用本地组件状态,而应使用useSelectoruseDispatch挂钩来读取和更新counter存储中的状态。

import { useDispatch, useSelector } from 'react-redux';

const Counter = () => {
  const dispatch = useDispatch();
  const count = useSelector(state => state.counter.count);

  const handleIncrement = () => {  
    dispatch({ type: handleIncrement });
  }

  const handleDecrement = () => {  
    dispatch({ type: handleDecrement });
  }

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

export default Counter;
Run Code Online (Sandbox Code Playgroud)