Я просто пытаюсь отправить действие в хранилище и получаю эту ошибку. Я понятия не имею, что такое прослушиватель2 и почему возникает ошибка типа:
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;
магазин.js:
import {configureStore} from '@reduxjs/toolkit';
import PostContainerReducer from './features/post/PostContainerSlice.js';
export default configureStore({
reducer: {
postContainer: PostContainerReducer
}
})
индекс.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);
Приложение.js:
import './App.css';
import PostContainer from './features/post/PostContainer'
function App(props) {
const {state, dispatch} = props;
dispatch({
type: 'postContainer/addPost',
payload: 'test'
})
console.info(state)
}
export default App;
Консольная регистрация состояния магазина работает нормально, причиной этого является просто диспетчеризация. При удалении «store.subscribe(root)» из index.js ошибка не возникает, но журналирование консоли показывает, что ничего не было отправлено и хранилище остается неизменным... возможно, это не имеет никакого отношения к проблеме. Кроме того, при отправке и регистрации состояния из index.js над рендерингом приложения магазин, похоже, отправляет и регистрирует нормально... подумал, что это подсказка, но ни к чему не привел.
🤔 А знаете ли вы, что...
React обеспечивает высокую производительность благодаря эффективной обработке изменений DOM.
«Слушатель», о котором здесь идет речь, — это функция обратного вызова слушателя, которая ожидает передачи.
Смотрите подписывайтесь(слушатель)
store.subscribe
не возвращает функцию.
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
Примечание. Однако мы используем Redux в React не так!
Вам следует импортировать и обернуть компонент ReactDOM.createRoot().render
в компонент App
react-redux
, чтобы предоставить контекст хранилища Redux приложению React.
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>
);
Компонент Provider
и все компоненты в суб-ReactTree должны импортировать и использовать хуки App
и useDispatch
из useSelector
для отправки действий в хранилище и подписки на выбранные обновления состояния.
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.info({ postContainer });
}, [postContainer]);
...
}
export default App;