Redux.js - 我无法使用 React Redux 映射StateToProps - 我的 React 组件块在商店初始状态上并且在 store.state 更新时无法更新

IT技术 javascript reactjs redux
2021-05-09 09:33:42

我目前正在尝试将包含的 app.state 传递到 React 组件中的 Redux 存储。

到目前为止,这个问题仍然是一个很深的谜……

------> 这里是我的代码的 GITHUB 存储库<------

希望它有助于找出问题所在。

抽象的 :

我的问题基本上是关于 mapStateToProps,是关于将一​​个组件链接到状态存储,AFAIK 其余的工作非常好,但是在 React 的组件中我的 this.props 似乎有些快捷方式,因为我要么使用 connect() 要么删除 mapStateToProps 方法,我的组件仍然显示初始状态..!

Redux 对我就像一个终端级别的老板一样抗拒......


比赛状态

  • 具有商店的提供者react-redux:OK
  • 连接函数传递给props:OK
  • mapDispatchToProps 工作正常!那么,既然连接似乎已经建立,那么为什么状态无法更新props呢?
    • 我知道我的动作被很好地映射,因为当我在连接组合中删除 mapDispatch 时,该组件无法触发相应的动作。
  • 当 console.log 时,mapState 有效地接收商店更新,但组件在初始状态下保持阻塞(使用组件上的“checkState”按钮进行测试,该按钮返回“store.getState().propertyTargeted”

提示:

  • 当我在connect中删除mapStateToProps时,我的React.Component继续接收initialState,所以也许有另一个源覆盖了我的mapStateToProps,我目前正在寻找它
  • 我的 this.props.state 变量在组件的构造函数中被调用,也许构造函数没有收到 store.updateState 或类似的东西?另一个跟踪。

这是我的 combineReducer.js :

import { combineReducers } from "redux";

import {post} from "./status"
import {entry}from "./updateState";

// only one reducer active 
const appReducer = combineReducers({ 
    entry,
    post

})
export default appReducer

这是我的 container.js :

const mapStateToProps = (state) => {

  return { word: state.entry.word }
}

const mapDispatchToProps = {
     postFile: postFileAction  
}

const PostFileContainer = connect(mapStateToProps, mapDispatchToProps)(Component) ;

我的 postFile.js :

export const postFile = (word, base64Data) => dispatch => {
  console.log("postFile httpRequest reached")

  dispatch({
    type: 'POST_WORD',
    status: request
  });
  Axios.post("http://localhost:7500/api/files", {
      "word": word,
      "data": base64Data

    }, {
      "Content-Type": "multipart/form-data"
    })
    .then(res =>
      dispatch({
        type: 'POST_WORD',
        status: success,
        res
      }))
    .catch(err => {
      dispatch({
        type: 'POST_WORD',
        status: error,
        err
      })
    });


}

在我的 store.initialState 中:

initial state: {
  "post": {},
  "entry": {
    "word": "initialWord"
  }
}

UPDATE_STATE_POSTWORD 是由其他 React 组件提供的,因此在窃听组件使用更新的单词条目触发它自己的操作之前将其分派到商店。 这是我的 UPDATE_STATE_POSTWORD 操作片段:

export const updateWord = word => {
  return {
    type: UPDATE_STATE_POSTWORD,
    word
  };
} 

/// reducers.js 部分 ///

postReducer.js :

  export const post = (state ={}, action) => {

  console.log("postStatus reached - reducer")
    switch (action.status) {
      case request:
        console.log("Request start")
        return state
      case success:
        switch (action.type) {
          case POST_FILE:
            console.log("request succeed: ", action.res)

            var _id = action.res._id
            // var word= action.res.word
            return (Object.assign({}, state, {
              _id 
            }))
          case POST_WORD:
            console.log("request succeed: ", action.res)
            return (Object.assign({}, state, {
              _id: ""
            }))
          default : 
            console.log(`default state on success case in
                         postStatusReducer`)
            return state
      }
      case error:
        console.log("request error: ", action.err)
        return state
      default:
        return state
    }

}

entryReducer.js :

 const initialState = { word : "initialWord" }
 export const updateStateReducer = (state= initialState, action) => 

{

    switch (action.type) {
        case UPDATE_STATE_POSTWORD:
            var word = action.word
            return (Object.assign({}, state, {
                word
            }))
        default:
            return state

    }
}

谢谢

2个回答

如果您正在使用react-thunk,您的操作 fn 将接收dispatchgetState用作参数。运行 getState 将为您提供应用程序的实际状态。Recuired 数据将传递给reducer 等等。

在您的示例中RecordingAPI仅在初始化时接收来自 redux 的props - 在构造函数中。您可以通过添加componentWillReceiveProps方法来修复您的组件

class RecordingAPI extends React.Component {
    constructor(props) {
        super(props);
        ...
        this.state = {
            word : this.props.word,
            state: this.props
        };
    }
    // new method that listens to props
    componentWillReceiveProps (props) {
        this.setState({
            word:   this.props.word,
            state:  this.props
        });
    }

    checkState(e){
        e.persist();
        e.preventDefault();
        e.stopPropagation();
        console.dir(this.state.word)
        console.dir(this.state.state)
    }

    render() {
        ...

        return (
            <div>
                <button onClick={(e) => this.checkState(e)}>  CheckState </button> 
            </div>
        );
    }
}

我目前的解决方法是直接在我的 React 组件中导入商店,然后订阅更改:

import {store} from "../App" 

    store.subscribe(() => {
      // When state will be updated
      // we will update local component state and force component to rerender 
      // with new data.

      this.setState({
        word: store.getState().entry.word // new entry.words at each update in the statge of the React.Component
      });
    });

回答 :

将 store.state 值分配给组件的状态构造函数,组件未能更新状态。因此,在对 Component.state.property 的任何赋值之外使用 this.props 来引用 store.state 就像一个魅力*。陷阱是,props.constructor.state当您只使用 React.js 时,将 props 存储在child 中是有效的,但是这种机制不适用于 React-Redux,那么您必须将 props 保留在props.constructor.state