React组件在状态改变时没有更新

3

我目前有一个reducer,它会对状态进行深度复制,并返回更新后的值。

function countableItems(state = initialState, action) {
    switch (action.type) {
        case types.ADD_TO_SUM:
            let denomMap = findDenomination(state.denomGroups, action),
                nestedCopy = Immutable.fromJS(state);
            return nestedCopy.setIn(['denomGroups', denomMap.group, denomMap.key, denomMap.index, 'sum'], parseFloat(action.value)).toJS();
        default:
            return state;
    }
}

在我的显示组件的渲染函数中,我可以看到正确的更新值在this.props.denoms中。 render() 函数构建了子元素<DenomInput> 组件,当我设置断点时我可以看到传入的数据是正确的。

render() {
    let denomGroups = this.props.denoms.map((denom, i) => {
        return (
            Object.keys(denom).map((key) => {
                let denoms = denom[key].map((item, i) => {
                    return <DenomInput denom={item} onDenomChange={this.onDenomChange} key={i}></DenomInput>
                });
                return (<div className="col"><h2>{key}</h2>{denoms}</div>)
            })
        );
    });

    return (
        <div className="countable-item-wrapper">
            <div className="row">
                {denomGroups}
            </div>
        </div>
    );
}

然而,当<DenomInput>组件被渲染时,它会呈现与最初设置的相同的值。
import React, { Component } from 'react';
import PropTypes from 'prop-types';

class DenomInput extends Component {
    constructor(props) {
        super(props);
        this.state = { denom: props.denom }
        this.handleKeyUp = this.handleKeyUp.bind(this);
    }

    handleKeyUp = (e) => {
        this.props.onDenomChange(e.target.value, this.state.denom.name);
    }

    render() {
        return (
            <div className="input-group denom">
                <span className="input-group-addon">{this.state.denom.label}</span>
                <input
                    type="text"
                    className="form-control"
                    onChange={this.handleKeyUp}
                    value={this.state.denom.sum} />

                <span className="input-group-addon">{this.state.denom.count | 0}</span>
            </div>
        );
    }
}

DenomInput.PropTypes = {
    denom: PropTypes.object.isRequired,
    onDenomChange: PropTypes.function
}

export default DenomInput;

我需要什么来使用React和Redux更新视图?

2个回答

6
也许componentWillReceiveProps可以解决问题。每当从父组件接收到新数据时,它将更新组件的状态,并再次调用render函数。请尝试。
class DenomInput extends Component {
    ...

    componentWillReceiveProps(nextProps) {
         this.setState({ denom: nextProps.denom })
    }
   ...
}

2
componentWillReceiveProps已被弃用。 - Pete Alvin
相关文章:https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html - XoXo

1
看起来你正在使用存储中的props来种子化初始状态。然后从组件状态呈现,但你从未更新组件状态。它们只会被设置一次,因为构造函数仅在组件被呈现时调用一次。要修复,请完全删除此组件状态并将其连接到redux store,或者在onChange时更新组件状态。我建议删除本地状态。我发现保持两个状态同步容易出错。
constructor(props) {
        super(props);
        this.state = { denom: props.denom }
        this.handleKeyUp = this.handleKeyUp.bind(this);
    }

    handleKeyUp = (e) => {
        this.props.onDenomChange(e.target.value, this.state.denom.name);
        this.setState({ denom: /*new state identitcal to change in redux store*/ })
    }

编辑2:提升状态的示例。步骤如下:
1. 使用mapStateToProps函数连接一个父组件,并获取适当的状态片段。
2. 通过连接的父组件将props传递给DenomInput。
4. 在this.denomsChange中分派适当的操作。由于您没有在帖子中包含操作,因此不清楚这是什么。

class DenomInput extends Component {
    ...
    render() {
        return (
            <div className="input-group denom">
                <span className="input-group-addon">{this.props.denom.label}</span>
                <input
                    type="text"
                    className="form-control"
                    onChange={this.handleKeyUp}
                    value={this.props.denom.sum} />

                <span className="input-group-addon">{this.props.denom.count | 0}</span>
            </div>
        );
    }
}


export default DenomInput;

数值在 <CountableItem> 中看起来正确,但在 <DenomInput> 中不正确。 - Jon Harding
注释中应该填什么值?state.count.denomGroups? - Jon Harding
我认为你应该先尝试@PriyeshKumar的答案,假设你正在正确地分派更新props的操作。总的来说,连接是最好的方法。 - Stephen L
我没想到你会在Redux中使用那些函数。 - Jon Harding
1
通常情况下你不需要这样做。问题在于你同时拥有组件状态和redux状态,而你正在使用redux状态props.denoms来填充你的组件状态:this.state = {denom: props.denom},然后在你的store中使用组件状态。由于你从未更新组件状态,所以你永远看不到组件中的更改。我会在我的评论中添加一个编辑,以展示我认为更一致/更少出错的选项。 - Stephen L
我的目标是<DenomInput>成为一个愚蠢的呈现组件,所以如果更喜欢删除其中一个状态,我希望能够学到这个。 - Jon Harding

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接