![](/img/trans.png)
[英]React Native & Redux: Why aren't child components re-rendering on every state update?
[英]React redux - parent state changing, but child components not re-rendering
我只是在嘗試學習使用redux,並且我有一個非常簡單的計數器列表組件,其中包含子計數器組件的列表。
我在計數器上有一個onIncrement動作,我想在單擊時增加計數。
當我單擊增量時,它將更新父狀態,但是子計數器不會更新。 如果我瀏覽然后返回列表,它確實可以正確渲染,在我看來這意味着狀態已更新。
這是我的代碼:
計數器組件
import React, { Component } from "react";
import { connect } from 'react-redux';
import { incrementCounter } from '../../actions/counterActions';
import PropTypes from 'prop-types';
class Counter extends Component {
render() {
return <div className="m-2">
<b>{this.props.counter.count}</b>
<button className="btn btn btn-secondary btn-sm m-2" onClick={() => { this.onIncrement(this.props.counter) }}>Increment</button>
</div>;
}
onIncrement(counter) {
this.props.incrementCounter(counter);
}
}
const mapStateToProps = state => ({
})
Counter.propTypes = {
incrementCounter: PropTypes.func.isRequired,
}
export default connect(mapStateToProps, { incrementCounter })(Counter);
計數器列表組件
import React, { Component } from "react";
import { RouteComponentProps } from "react-router";
import { CounterContext } from "../../contexts/context.js";
import Counter from "./Counter";
import { NewItem } from "./NewItem";
import ItemContainer from "../layout/ItemContainer";
import { connect } from 'react-redux';
import { getCounters } from '../../actions/counterActions';
import PropTypes from 'prop-types';
class CounterList extends Component {
componentWillMount() {
if (this.props.counters.length == 0) {
this.props.getCounters();
}
}
render() {
const counterItems = this.props.counters.map(counter => <Counter key={counter.id} counter={counter} />);
return <div>{ counterItems }</div>;
}
}
const mapStateToProps = state => ({
counters: state.counters.items
})
CounterList.propTypes = {
getCounters: PropTypes.func.isRequired,
counters: PropTypes.array.isRequired
}
export default connect(mapStateToProps, { getCounters })(CounterList);
反行動
import { GET_COUNTERS, INCREMENT_COUNTERS } from '../actions/types';
export const getCounters = () => dispatch => {
const counters = [{ id: 1, count: 4 }, { id: 2, count: 3 }, { id: 3, count: 0 }];
// this could be API call to get initial counters
console.log('In GetCounters', GET_COUNTERS);
return dispatch({
type: GET_COUNTERS,
payload: counters
})
}
export const incrementCounter = (counter) => dispatch => {
// this could be API call to get initial counters
counter.count++;
return dispatch({
type: INCREMENT_COUNTERS,
payload: counter
})
}
減速機
import { GET_COUNTERS, INCREMENT_COUNTERS } from '../actions/types';
const initialState = {
items: []
}
export default function (state = initialState, action) {
console.log(action.type);
switch (action.type){
case GET_COUNTERS:
return {
...state,
items: action.payload
};
case INCREMENT_COUNTERS:
var counter = action.payload;
const counters = [...state.items];
const index = counters.findIndex(x => x.id == counter.id);
counters[index] = counter;
return {
...state,
items: counters
};
default:
return state;
}
}
我想問題可能是您正在將具有更新的count值的相同舊計數器對象分配給counters [index],因此Counter組件看不到變化。 這可能是因為shouldComponentUpdate進行了淺層檢查,並且對計數器prop的對象引用保持不變,並且您的組件不會重新呈現。
如果您在狀態中使用多維數組或嵌套對象,則應該使用深度克隆。
建議使用Immutable.js之類的庫,以確保您的減速器保持純凈。
case INCREMENT_COUNTERS: var counter = action.payload; const counters = JSON.parse(JSON.stringify(state.items)); //this creates a deep copy const index = counters.findIndex(x => x.id == counter.id); counters[index].count = counter.count; return { ...state, items: counters };
您沒有將狀態映射到道具,例如:
function mapStateToProps = state => {
return { count: state.count };
}
這將在您的redux中映射狀態,以反映計數器的變化到您要顯示當前計數的組件的props。 希望這可以幫助!
您可以嘗試將componentWillReceiveProps
放入Counter
組件中,並在每次單擊按鈕時檢查是否獲得了新的counter
prop。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.