简体   繁体   English

反应组件不会随着状态变化而更新

[英]React Component not updating with state change

I currently have a reducer that does a deep copy of state and returns it with the updated value. 我目前有一个化简器,可以对状态进行深层复制,并以更新后的值返回它。

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;
    }
}

In my render function of the display Component I see the correct updated values in this.props.denoms The render() function builds up child <DenomInput> components, and when I set my breakpoints I see the correct data being passed in 在显示组件的渲染函数中,我在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>
    );
}

However when the <DenomInput> components render it renders the same value as what they were initially set 但是,当<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;

What piece am I missing to update the view with React and Redux? 我缺少用React和Redux更新视图的哪一部分?

May be componentWillReceiveProps can do the trick. 可能由componentWillReceiveProps可以解决。 It will update the state of the component whenever new data is receive from parent, and call the render function again. 每当从父级接收到新数据时,它将更新组件的状态,并再次调用render函数。

Try 尝试

class DenomInput extends Component {
    ...

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

It looks like you're seeding your initial state with the props from your store. 看来您正在使用商店中的道具播种初始状态。 You then render from the component state, but you never update the component state. 然后,您从组件状态进行渲染,但从不更新组件状态。 They only get set once because constructor is only called once the component is rendered. 它们仅设置一次,因为构造器仅在组件呈现后才调用。 To fix, either remove this component state entirely and just connect it to the redux store, or update the component state onChange. 要解决此问题,请完全删除该组件状态,然后将其连接到redux存储,或更新onChange组件状态。 I recommend removing the local state. 我建议删除本地状态。 I have found that keeping the two states in sync is error-prone. 我发现使两个状态保持同步很容易出错。

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*/ })
    }

edit2: An example of raising state up. edit2:提升状态的示例。 The steps are: 这些步骤是:
1. Connect one of your parent components and grab the appropriate slice of state with a mapStateToProps function. 1.连接您的父组件之一,并使用mapStateToProps函数获取适当的状态片段。
2. Pass the props through your connected parent component to DenomInput. 2.将道具通过连接的父组件传递到DenomInput。
4. In this.denomsChange, dispatch the appropriate action. 4.在this.denomsChange中,调度适当的操作。 It is unclear what this is since you did not include your action in the post. 目前尚不清楚这是什么,因为您没有在帖子中包含您的操作。

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM