javascript - React 组件道具不会随 redux 商店更新
问题描述
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
我的问题是组件的道具似乎没有用 redux 商店更新。在 onClick 函数运行后,redux 存储更新为正确的值,mapStateToProps 也以正确的状态运行,如果我尝试从 prop 记录状态,我仍然会得到旧值。如果我在返回 JSX 之前在渲染函数中执行相同的日志,我会从道具中获得正确的状态,我无法理解为什么在 redux 存储之后它没有立即更新。因此,如果我将代码修改为以下内容,它将按预期工作:
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 完全建立在函数式编程上,现在有了 hooks,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()
一旦第一次调用结束,将获得新值,然后循环再次重复。
Action dispatchers 将从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())
}
推荐阅读
- android - 在 Android 应用程序中使用移动数据访问互联网时使用没有网关/互联网连接的本地 Wifi (Flutter)
- python - 如何将元组中的特定值传递给函数
- mathematical-optimization - 如何获得千里眼重启所需的时间?
- awk - awk:如何仅在大于或小于负数之间打印
- python - 我想从 python-flask 中聚合函数的 sqlalchemy 查询中打印值
- powerbi - Power BI Dax 从现有列创建新表
- elasticsearch - 使用多个索引嵌套 ElasticClient 以索引文档
- c++ - 防止简单的宏替换
- android - Flutter“此函数的返回类型为void,无法使用”
- grpc - 无法在 QNX 上运行 greeter_client helloworld 示例项目