You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Redux开发社交应用遇this._state未定义及dispatch问题求助

Redux状态管理问题修复方案

问题分析

当前存在两个核心问题:

  1. store.js中访问this._state时提示"this._state is undefined"
  2. MyPosts.jsx中props.dispatch(action)执行异常,同时props.newPostText、props.posts无法获取正确值

问题1:this._state is undefined的修复

原因

  • _callSubscriber方法调用时,this未绑定到store实例,导致内部this指向全局/undefined
  • addPostActionCreator未接收传入的text参数,导致新增post时无法获取输入内容

修复步骤

  1. 将_callSubscriber改为直接引用store实例,避免this指向混乱
  2. 修正addPostActionCreator,接收text参数并传入action对象

问题2:MyPosts.jsx中dispatch与props映射问题修复

原因

  • connect方法仅传入null,未将Redux state映射到组件props,导致props.newPostText、props.posts为undefined
  • 结合store的this指向问题,进一步导致dispatch执行异常

修复步骤

  1. 编写mapStateToProps函数,将store中的newPostText和posts映射到组件props
  2. 通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:06:02