Redux:re-rendering children 存储状态更新
Redux: re-rendering children on store state update
最近开始学习react
+ redux
。在此之前,我没有使用过此类堆栈的经验。
所以我 运行 遇到了一个问题,我不明白为什么当减速器 returns 新状态时 child 组件没有得到 re-rendered 。
Full code on GITHUB
这是我的 parent 组件 source on git:
import React from "react"
import {connect} from "react-redux"
import {fetchWarehouses} from "../../actions/warehouseActions"
import WarehouseMenu from "./WarehouseMenu"
import WarehouseView from "./WarehouseView"
import WarehouseEdit from "./WarehouseEdit"
@connect((store) => {
return {
warehouses: store.warehouses.warehouses,
selectedWarehouse: store.warehouses.selectedWarehouse,
isSelected: store.warehouses.isSelected,
warehouseCount: store.warehouses.warehouseCount,
}
})
export default class WarehousePage extends React.Component {
componentWillMount() {
this.props.dispatch(fetchWarehouses())
}
render() {
return (
<div className="container-fluid">
<div className="row">
<div className="col-sm-2">
Warehouses ({this.props.warehouseCount}):
</div>
<div className="col-sm-10">
<WarehouseMenu warehouseList={this.props.warehouses} />
</div>
</div>
<div className="col-lg-12">
<WarehouseView test={this.props.isSelected} selectedWarehouse={this.props.selectedWarehouse} />
</div>
<div className="col-lg-12">
<WarehouseEdit />
</div>
</div>
)
}
}
而这些是children source on git:
import React from "react"
import store from "../../store"
import {fetchOne} from "../../actions/warehouseActions"
export default class WarehouseMenu extends React.Component {
constructor(props) {
super(props)
}
select(id) {
store.dispatch(fetchOne(id))
}
render() {
const {warehouseList} = this.props.warehouseList
if (!warehouseList) {
return <button className="btn btn-success" key="new_warehouse">+</button>
}
const mappedWarehouses = warehouseList.map(wh => <button onClick={this.select.bind(this, wh.id)} className="btn btn-default" key={wh.id}>{wh.name}</button>)
mappedWarehouses.push(<button className="btn btn-success" key="new_warehouse">+</button>)
return (
<div className="btn-group">
{mappedWarehouses}
</div>
)
}
}
import React from "react"
import store from "../../store"
import {deleteWarehouse, fetchWarehouses} from "../../actions/warehouseActions"
export default class WarehouseView extends React.Component {
constructor(props) {
super(props)
}
render() {
const {test, selectedWarehouse} = this.props
if (!test) {
return null
}
return (
<div className="container-fluid">
<div className="row">
<div className="col-sm-2">
ID
</div>
<div className="col-sm-10">
{selectedWarehouse.id}
</div>
</div>
<div className="row">
<div className="col-sm-2">
Name
</div>
<div className="col-sm-10">
{selectedWarehouse.name}
</div>
</div>
<div className="row">
<div className="col-sm-12">
<button className="btn btn-warning">EDIT</button>
<button onClick={this.deleteWarehouse.bind(this, selectedWarehouse.id)} className="btn btn-danger">DELETE</button>
</div>
</div>
</div>
)
}
deleteWarehouse(id) {
store.dispatch(deleteWarehouse(id))
}
}
因此,每当我发送 deleteWarehouse
时,我都希望 WarehouseMenu
重新呈现,因为 store.warehouses.warehouses
的状态发生了变化。我没有得到预期的结果。只有 WarehousePage
重新呈现(例如 store.warehouses.warehouseCount
)。我试过 @connect
int store to child components 但似乎也没有得到想要的结果。
您的删除操作:
export function deleteWarehouse(id) {
return function (dispatch) {
axios.delete(`/api/sandy/api/warehouses/${id}`)
.then((response) => {
dispatch({
type: "DELETE_WAREHOUSE_FULFILLED",
payload: null
})
})
.catch((err) => {
})
}
}
从不更新状态以从warehouseReducers.js
中的state.warehouses
数组中删除已删除的仓库:
case "DELETE_WAREHOUSE_FULFILLED": {
return {...state,
selectedWarehouse: null,
isSelected: false,
warehouseCount: state.warehouseCount - 1
}
}
当调度 DELETE_WAREHOUSE_FULFILLED
动作时,您没有更改 warehouseReducers.js
中的 warehouses
属性,但您确实更改了 warehouseCount
最近开始学习react
+ redux
。在此之前,我没有使用过此类堆栈的经验。
所以我 运行 遇到了一个问题,我不明白为什么当减速器 returns 新状态时 child 组件没有得到 re-rendered 。
Full code on GITHUB
这是我的 parent 组件 source on git:
import React from "react"
import {connect} from "react-redux"
import {fetchWarehouses} from "../../actions/warehouseActions"
import WarehouseMenu from "./WarehouseMenu"
import WarehouseView from "./WarehouseView"
import WarehouseEdit from "./WarehouseEdit"
@connect((store) => {
return {
warehouses: store.warehouses.warehouses,
selectedWarehouse: store.warehouses.selectedWarehouse,
isSelected: store.warehouses.isSelected,
warehouseCount: store.warehouses.warehouseCount,
}
})
export default class WarehousePage extends React.Component {
componentWillMount() {
this.props.dispatch(fetchWarehouses())
}
render() {
return (
<div className="container-fluid">
<div className="row">
<div className="col-sm-2">
Warehouses ({this.props.warehouseCount}):
</div>
<div className="col-sm-10">
<WarehouseMenu warehouseList={this.props.warehouses} />
</div>
</div>
<div className="col-lg-12">
<WarehouseView test={this.props.isSelected} selectedWarehouse={this.props.selectedWarehouse} />
</div>
<div className="col-lg-12">
<WarehouseEdit />
</div>
</div>
)
}
}
而这些是children source on git:
import React from "react"
import store from "../../store"
import {fetchOne} from "../../actions/warehouseActions"
export default class WarehouseMenu extends React.Component {
constructor(props) {
super(props)
}
select(id) {
store.dispatch(fetchOne(id))
}
render() {
const {warehouseList} = this.props.warehouseList
if (!warehouseList) {
return <button className="btn btn-success" key="new_warehouse">+</button>
}
const mappedWarehouses = warehouseList.map(wh => <button onClick={this.select.bind(this, wh.id)} className="btn btn-default" key={wh.id}>{wh.name}</button>)
mappedWarehouses.push(<button className="btn btn-success" key="new_warehouse">+</button>)
return (
<div className="btn-group">
{mappedWarehouses}
</div>
)
}
}
import React from "react"
import store from "../../store"
import {deleteWarehouse, fetchWarehouses} from "../../actions/warehouseActions"
export default class WarehouseView extends React.Component {
constructor(props) {
super(props)
}
render() {
const {test, selectedWarehouse} = this.props
if (!test) {
return null
}
return (
<div className="container-fluid">
<div className="row">
<div className="col-sm-2">
ID
</div>
<div className="col-sm-10">
{selectedWarehouse.id}
</div>
</div>
<div className="row">
<div className="col-sm-2">
Name
</div>
<div className="col-sm-10">
{selectedWarehouse.name}
</div>
</div>
<div className="row">
<div className="col-sm-12">
<button className="btn btn-warning">EDIT</button>
<button onClick={this.deleteWarehouse.bind(this, selectedWarehouse.id)} className="btn btn-danger">DELETE</button>
</div>
</div>
</div>
)
}
deleteWarehouse(id) {
store.dispatch(deleteWarehouse(id))
}
}
因此,每当我发送 deleteWarehouse
时,我都希望 WarehouseMenu
重新呈现,因为 store.warehouses.warehouses
的状态发生了变化。我没有得到预期的结果。只有 WarehousePage
重新呈现(例如 store.warehouses.warehouseCount
)。我试过 @connect
int store to child components 但似乎也没有得到想要的结果。
您的删除操作:
export function deleteWarehouse(id) {
return function (dispatch) {
axios.delete(`/api/sandy/api/warehouses/${id}`)
.then((response) => {
dispatch({
type: "DELETE_WAREHOUSE_FULFILLED",
payload: null
})
})
.catch((err) => {
})
}
}
从不更新状态以从warehouseReducers.js
中的state.warehouses
数组中删除已删除的仓库:
case "DELETE_WAREHOUSE_FULFILLED": {
return {...state,
selectedWarehouse: null,
isSelected: false,
warehouseCount: state.warehouseCount - 1
}
}
当调度 DELETE_WAREHOUSE_FULFILLED
动作时,您没有更改 warehouseReducers.js
中的 warehouses
属性,但您确实更改了 warehouseCount