调度导致 TypeError 'listener2 不是函数”

问题描述 投票:0回答:1

我只是尝试向商店发送一个操作,但收到此错误。我不知道 Listener2 是什么,也不知道为什么会出现 TypeError:

listener2 is not a function
TypeError: listener2 is not a function
    at wrappedListener
    at Map.forEach (<anonymous>)
    at Object.dispatch
    at dispatch
    at App

这是我唯一的一片:

import {createSlice} from '@reduxjs/toolkit';

const PostContainerSlice = createSlice({
  name: "postContainer",
  initialState: [],
  reducers: {
    addPost: (state, action) => {
      state.push(action.payload)
    },
  }
})

export const {addPost} = PostContainerSlice.actions;
export default PostContainerSlice.reducer;

store.js:

import {configureStore} from '@reduxjs/toolkit';
import PostContainerReducer from './features/post/PostContainerSlice.js';

export default configureStore({
  reducer: {
    postContainer: PostContainerReducer
  }
})


index.js:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import store from './store.js';

const root = ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
      <App dispatch={store.dispatch} state={store.getState()} />
  </React.StrictMode>
);

store.subscribe(root);

App.js:

import './App.css';
import PostContainer from './features/post/PostContainer'

function App(props) {
  const {state, dispatch} = props;

  dispatch({
    type: 'postContainer/addPost',
    payload: 'test'
  })
  console.log(state)

 
}

export default App;

控制台记录商店的状态工作正常,只是调度导致了这种情况。从 index.js 中删除“store.subscribe(root)”时,不会发生错误,但控制台日志记录显示没有调度任何内容,并且商店保持不变......也许这与问题无关。 另外,当从应用程序渲染上方的 index.js 调度和记录状态时,商店似乎正常调度和记录......认为这是一个线索,但没有引导我。

reactjs redux react-redux redux-toolkit
1个回答
0
投票

问题

这里所说的“监听器”是

store.subscribe
期望传递的监听器回调函数。

参见订阅(监听器)

ReactDOM.createRoot().render
不返回函数。

const root = ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
      <App dispatch={store.dispatch} state={store.getState()} />
  </React.StrictMode>
);

store.subscribe(root); // root is not a function

解决方案

您也许可以创建一个函数来渲染应用程序,该应用程序也可以充当侦听器回调。

示例:

const root = ReactDOM.createRoot(document.getElementById('root'));

const renderApp = () => { 
  root.render(
    <React.StrictMode>
      <App dispatch={store.dispatch} state={store.getState()} />
    </React.StrictMode>
  );
};

renderApp(); // <-- call once to initially render app

store.subscribe(renderApp); // <-- pass as listener to rerender with state changes

注意:不是我们在React中使用Redux的方式!

您应该在

App
react-redux
组件中导入并包装
Provider
组件,以便为 React 应用程序提供 Redux 存储上下文。

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';
import store from './store.js';

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

App
组件以及子 ReactTree 中的所有组件,应导入并使用
useDispatch
中的
useSelector
react-redux
钩子将操作分派到存储,并订阅选定的状态更新。

import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import './App.css';
import PostContainer from './features/post/PostContainer'

function App() {
  const dispatch = useDispatch();
  const postContainer = useSelector(state => state.postContainer);

  useEffect(() => {
    dispatch({
      type: 'postContainer/addPost',
      payload: 'test'
    });
  }, [dispatch]);

  useEffect(() => {
    console.log({ postContainer });
  }, [postContainer]);
 
  ...
}

export default App;
© www.soinside.com 2019 - 2024. All rights reserved.