redux 如何修复无法读取null的属性(阅读'useContext')?

wkftcu5l  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(339)

我找不到罪魁祸首在哪里.我试着调试它,却找不到真正使它出错的那些东西:
无法读取null的属性(阅读'useContext')&& react.development.js:209警告:无效的挂接调用。只能在函数组件的主体内部调用挂接。这可能是由于以下原因之一造成的:

  1. React和渲染器的版本可能不匹配(例如React DOM)
    1.你可能违反了钩子的规则
    1.您可能在同一个应用程序中有多个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;
pbpqsu0x

pbpqsu0x1#

问题

Store不是React组件,因此它不能使用useStore挂钩。
useStore
此挂接返回一个对传入<Provider>组件的同一Redux存储的引用。
换句话说,useStore钩子期望从ReactTree中的较高位置向其提供Redux上下文。

溶液

从我所知道的代码来看,您似乎希望Store函数创建并返回一个Redux存储对象,以传递给Provider组件。
store.js

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

const rootReducer = combineReducers({
  counter,
});

const store = createStore(rootReducer);

export default store;

类型

export const handleIncrement = 'handleIncrement' ;
export const handleDecrement = 'handleDecrement';

counter.reducer.js
reducer函数应该保持状态不变。在这种情况下,状态是一个具有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;
  }
};

index.js

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

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

计数器
组件应使用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;

相关问题