React 组件道具不会使用 redux 商店更新

b.szombor

Button.js 组件

    import React from "react"
import "../styles/button.scss"
import store from "../index"

class Button extends React.Component {
    constructor(props) {
        super(props)
        this.buttonTextChanger()
    }

    buttonTextChanger() {
        this.buttonText = "MainPage" === this.props.state.page ? "Az adatokhoz" : "A főoldalra"
    }


    logger = (actualPage) => {
        this.props.onButtonClick(actualPage)
        console.log("state from store before textchange", store.getState())
        console.log("state from props before textchange", this.props.state)
        this.buttonTextChanger()
    }

    render() {
        return (
            <div id="container">
                <button className="learn-more" onClick = {() => this.logger(this.props.state.page)}>
                    <span className="circle" aria-hidden="true">
                    <span className="icon arrow"></span>
                    </span>
                    <span className="button-text">{this.buttonText}</span>
                </button>
            </div>
        )
    }
}

export default Button

我的问题是组件的 props 似乎没有用 redux store 更新。在 onClick 函数运行后,redux 存储更新为正确的值,mapStateToProps 也以正确的状态运行,并且在这些之后,如果我尝试从 prop 记录状态,我会得到旧值。如果我在返回 JSX 之前在渲染函数中执行相同的日志,我会从 props 获得正确的状态,并且我无法理解为什么在 redux store 之后它没有立即更新。因此,如果我将代码修改为以下内容,它会按预期工作:

logger = (actualPage) => {
        this.props.onButtonClick(actualPage)
        console.log("state from store before textchange", store.getState())

    }

    render() { 
        console.log("state from props before textchange", this.props.state)
        this.buttonTextChanger()  
        return (
            <div id="container">
                <button className="learn-more" onClick = {() => this.logger(this.props.state.page)}>
                    <span className="circle" aria-hidden="true">
                    <span className="icon arrow"></span>
                    </span>
                    <span className="button-text">{this.buttonText}</span>
                </button>
            </div>
        )
    }
}

减速机功能

import { combineReducers } from "redux"

export const changePageReducer = (state = {page : "MainPage"}, action) => {
    if (action.type === "CHANGE_PAGE")
        if (action.payload !== state.page) {
            return action.payload
        }

    return state.page
}

export const combinedReducers = combineReducers({page : changePageReducer})

按钮容器

import { connect } from "react-redux"
import Button from "../components/Button"
import changePage from "../actions/changePage"

const mapStateToProps = (state) => {
    console.log("az injectelt state", state)
    return {state}
} 

const mapDispatchToProps = (dispatch) => {
    return {
        onButtonClick : (page) => {
            switch (page) {
                case "MainPage":
                    dispatch(changePage("DataPage"))
                    break
                case "DataPage":
                    dispatch(changePage("MainPage"))
                    break
                default:
                    dispatch(changePage("MainPage"))
            }
        }
    }
}

const ChangePageContainer = connect(mapStateToProps, mapDispatchToProps)(Button)

export default ChangePageContainer

但我想从渲染函数中提取 buttonTextChanger() 函数调用并在单击时调用它。

TLDR:问题:

logger = (actualPage) => {
  console.log("prop state value before dispatch", this.props.state)
  console.log("store value before dispatch", store.getState())
  this.props.onButtonClick(actualPage)
  console.log("prop state value after dispatch", this.props.state)
  console.log("store value after dispatch", store.getState())
}

mapStateToProps 函数中还有一个 console.log 来查看传递给 props 的状态。这产生:

prop state value before dispatch {page: "MainPage"}
store value before dispatch {page: "MainPage"}
state when mapStateToProps function called {page: "DataPage"}
store value after dispatch {page: "DataPage"}
prop state value after dispatch {page: "MainPage"}

所以道具不会更新。

普希金

因此,您无法理解为什么this.props.state即使在调用调度员后仍未更新?

你看,Redux 完全建立在函数式编程之上,现在有了钩子,React 也完全转向了函数式编程,地狱甚至 JavaScript 最初是作为函数式编程构建的。

与 OOP 完全不同且最酷的一件事是,函数式编程中没有突变。没有。Vanilla Redux 是完全的 FP,只有纯函数——没有副作用的函数。这就是为什么你需要 Redux Saga 或其他库来进行 API 调用——非纯函数。

切入正题,

logger = (actualPage) => {
  // here,
  // actualPage => new value
  // this.props.state => old value
  // they will remain as such throughout this function


  console.log("prop state value before dispatch", this.props.state)
  console.log("store value before dispatch", store.getState())
  this.props.onButtonClick(actualPage)

  // even if you update the Redux Store, 
  // `this.props.state` will still have the old value
  // since this value will not be mutated

  console.log("prop state value after dispatch", this.props.state)
  console.log("store value after dispatch", store.getState())
}

然后呢store.getState(),它们的值被更新了,你可能会问。

请注意它不是store.getState而是而是store.getState()是的,它是一个函数而不是一个值。每当您调用它们时,它们都会返回最新值,并且它们中没有任何突变。在您的情况下,您在调度操作后第二次调用,因此您将获得最新值。这不是突变,store.getState()只是获取了最新的值并将其返回给您。logger()一旦第一次调用结束,将获得新值,然后循环再次重复。

动作调度器将从state旧的中创建新state,这就是为什么您可以在 Redux DevTools 中进行时间旅行。

再次回顾

logger = (actualPage) => {
  // old value
  console.log("prop state value before dispatch", this.props.state)
  // old value
  console.log("store value before dispatch", store.getState())

  // new value
  this.props.onButtonClick(actualPage)
  // redux would be updated with new values by now

  // but still old value - no mutation
  console.log("prop state value after dispatch", this.props.state)
  // new value
  console.log("store value after dispatch", store.getState())
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章