React+Redux开发社交应用遇this._state未定义及dispatch问题求助
Redux状态管理问题修复方案
问题分析
当前存在两个核心问题:
- store.js中访问
this._state时提示"this._state is undefined" - MyPosts.jsx中
props.dispatch(action)执行异常,同时props.newPostText、props.posts无法获取正确值
问题1:this._state is undefined的修复
原因
_callSubscriber方法调用时,this未绑定到store实例,导致内部this指向全局/undefinedaddPostActionCreator未接收传入的text参数,导致新增post时无法获取输入内容
修复步骤
- 将
_callSubscriber改为直接引用store实例,避免this指向混乱 - 修正
addPostActionCreator,接收text参数并传入action对象
问题2:MyPosts.jsx中dispatch与props映射问题修复
原因
connect方法仅传入null,未将Redux state映射到组件props,导致props.newPostText、props.posts为undefined- 结合store的
this指向问题,进一步导致dispatch执行异常
修复步骤
- 编写
mapStateToProps函数,将store中的newPostText和posts映射到组件props - 通过
mapDispatchToProps直接绑定action creator,简化组件内的dispatch调用,同时避免手动调用dispatch的潜在问题
修改后的完整代码
store.js
let i = 900 let store = { _state: { newPostText: '', contacts: [ { name: "Paul", id: 1 }, { name: "Bob", id: 2 }, { name: "Serena", id: 3 }, { name: "Steve", id: 4 }, { name: "Michael", id: 5 }, { name: "Max", id: 6 }, { name: "Billy", id: 7 }, { name: "Tom", id: 8 }, { name: "George", id: 9 }, { name: "John", id: 10 }, { name: "Mike", id: 11 }, { name: "David", id: 12 }, { name: "Luke", id: 13 }, { name: "Liam", id: 14 }, { name: "Emma", id: 15 }, { name: "Olivia", id: 16 }, { name: "Noah", id: 17 }, { name: "Emma", id: 18 }, { name: "Olivia", id: 19 }, { name: "Noah", id: 20 }, { name: "Emma", id: 21 }, { name: "Olivia", id: 22 }, { name: "Noah", id: 23 } ], posts: [ { content: "Hey how r y'all doin'?", likes: 12, dislikes: 5 }, { content: 'whasup', likes: 41, dislikes: 2 }, { content: 'Eh? What? ', likes: 84, dislikes: 15 }, ], messages: [ { content: "Hello", seenByMe: true, seenByOther: false, isSender: true, time: "18:00" }, { content: "How are you?", seenByMe: false, seenByOther: true, isSender: false, time: "18:10" }, { content: "I'm good, thanks!", seenByMe: true, seenByOther: true, isSender: true, time: "18:12" }, { content: "Did you watch the game last night?", seenByMe: true, seenByOther: false, isSender: false, time: "18:15" }, { content: "No, I missed it. Who won?", seenByMe: false, seenByOther: true, isSender: true, time: "18:16" }, { content: "The home team won. It was an exciting match!", seenByMe: false, seenByOther: false, isSender: false, time: "18:17" }, { content: "That's great! I'll catch the highlights later.", seenByMe: true, seenByOther: false, isSender: true, time: "18:20" } ] }, getState(){ return this._state }, rerenderEntireTree() { this._state = { ...this._state } console.log('State changed') }, // 直接引用store实例,避免this指向问题 _callSubscriber(){ store._rerenderEntireTree(store._state) }, subscribe(observer) { this._rerenderEntireTree = observer }, dispatch(action) { if (action.type === 'ADD-POST') { let newPost = { content: action.text || this._state.newPostText, likes: 0, dislikes: 0 }; this._state.posts.push(newPost); this._state.newPostText = ''; this._callSubscriber(); i++; } else if (action.type === 'UPDATE-NEW-POST-TEXT') { this._state.newPostText = action.newText; this._callSubscriber(); } } } // 修正action creator,接收text参数 let addPostActionCreator = (text) => { return { type: 'ADD-POST', text: text } } let updateNewPostTextActionCreator = (text) => { return { type: 'UPDATE-NEW-POST-TEXT', newText: text } } export {addPostActionCreator, updateNewPostTextActionCreator} export default store window.store = store
MyPosts.jsx
import React, { useRef } from "react"; import cls from './MyPosts.module.css'; import Post from "./Post/Post"; import { connect } from "react-redux"; import { addPostActionCreator, updateNewPostTextActionCreator } from "../../../redux/store"; const MyPosts = (props) => { let newPostElement = useRef(); let addPost = () => { let text = newPostElement.current.value; props.addPost(text); }; let onPostChange = () => { let text = newPostElement.current.value; props.updateNewPostText(text); } return ( <div className={cls.postsComponent}> <h4>My posts</h4> <textarea onChange={onPostChange} className={cls.textarea} ref={newPostElement} value={props.newPostText}/> <input type="button" onClick={addPost} className={cls.button} value="Send"/> <div className={cls.posts}> <Post posts={props.posts} /> </div> </div> ); }; // 将state映射到组件props const mapStateToProps = (state) => { return { newPostText: state.newPostText, posts: state.posts } } // 将action creator绑定到dispatch,直接作为props传入组件 const mapDispatchToProps = (dispatch) => { return { addPost: (text) => dispatch(addPostActionCreator(text)), updateNewPostText: (text) => dispatch(updateNewPostTextActionCreator(text)) } } export default connect(mapStateToProps, mapDispatchToProps)(MyPosts);
index.js
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import { BrowserRouter } from 'react-router-dom'; import {Provider} from 'react-redux'; import {StrictMode} from 'react'; import {createRoot} from 'react-dom/client'; import store from './redux/store' const rootElement = document.getElementById('root'); const root = createRoot(rootElement); console.log('store in index.js:' + store.getState()) console.log(store) let rerenderEntireTree = (state) => { root.render( <StrictMode> <BrowserRouter> <Provider store={store}> <App /> </Provider> </BrowserRouter> </StrictMode> ) } rerenderEntireTree(store.getState()) store.subscribe(rerenderEntireTree) reportWebVitals();
内容的提问来源于stack exchange,提问作者Batiste HERBEZ
相关产品推荐
相关产品推荐

